public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Michal Hocko <mhocko-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
To: Vlastimil Babka <vbabka-AlSwsSmVLrQ@public.gmane.org>
Cc: nbd-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-block-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org,
	Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>,
	Andrew Morton
	<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	Mel Gorman
	<mgorman-3eNAlZScCAx27rWaFMvyedHuzzzSOjJt@public.gmane.org>
Subject: Re: [PATCH 2/4] mm: introduce memalloc_noreclaim_{save, restore}
Date: Wed, 5 Apr 2017 13:28:18 +0200	[thread overview]
Message-ID: <20170405112817.GK6035@dhcp22.suse.cz> (raw)
In-Reply-To: <20170405074700.29871-3-vbabka-AlSwsSmVLrQ@public.gmane.org>

On Wed 05-04-17 09:46:58, Vlastimil Babka wrote:
> The previous patch has shown that simply setting and clearing PF_MEMALLOC in
> current->flags can result in wrongly clearing a pre-existing PF_MEMALLOC flag
> and potentially lead to recursive reclaim. Let's introduce helpers that support
> proper nesting by saving the previous stat of the flag, similar to the existing
> memalloc_noio_* and memalloc_nofs_* helpers. Convert existing setting/clearing
> of PF_MEMALLOC within mm to the new helpers.
> 
> There are no known issues with the converted code, but the change makes it more
> robust.
> 
> Suggested-by: Michal Hocko <mhocko-IBi9RG/b67k@public.gmane.org>
> Signed-off-by: Vlastimil Babka <vbabka-AlSwsSmVLrQ@public.gmane.org>

One could argue that tsk_restore_flags() could be extended to provide
tsk_set_flags() and use it for all allocation related PF flags. I do not
have a strong opinion on that but explicit API sounds a bit better to me
because is easier to follow (at least for me). If others think that
generic API would be better then I won't have any objections. Anyway
this looks good to me.
Acked-by: Michal Hocko <mhocko-IBi9RG/b67k@public.gmane.org>

> ---
>  include/linux/sched/mm.h | 12 ++++++++++++
>  mm/page_alloc.c          | 11 ++++++-----
>  mm/vmscan.c              | 17 +++++++++++------
>  3 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
> index 9daabe138c99..2b24a6974847 100644
> --- a/include/linux/sched/mm.h
> +++ b/include/linux/sched/mm.h
> @@ -191,4 +191,16 @@ static inline void memalloc_nofs_restore(unsigned int flags)
>  	current->flags = (current->flags & ~PF_MEMALLOC_NOFS) | flags;
>  }
>  
> +static inline unsigned int memalloc_noreclaim_save(void)
> +{
> +	unsigned int flags = current->flags & PF_MEMALLOC;
> +	current->flags |= PF_MEMALLOC;
> +	return flags;
> +}
> +
> +static inline void memalloc_noreclaim_restore(unsigned int flags)
> +{
> +	current->flags = (current->flags & ~PF_MEMALLOC) | flags;
> +}
> +
>  #endif /* _LINUX_SCHED_MM_H */
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index b84e6ffbe756..037e32dccd7a 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -3288,15 +3288,15 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
>  		enum compact_priority prio, enum compact_result *compact_result)
>  {
>  	struct page *page;
> -	unsigned int noreclaim_flag = current->flags & PF_MEMALLOC;
> +	unsigned int noreclaim_flag;
>  
>  	if (!order)
>  		return NULL;
>  
> -	current->flags |= PF_MEMALLOC;
> +	noreclaim_flag = memalloc_noreclaim_save();
>  	*compact_result = try_to_compact_pages(gfp_mask, order, alloc_flags, ac,
>  									prio);
> -	current->flags = (current->flags & ~PF_MEMALLOC) | noreclaim_flag;
> +	memalloc_noreclaim_restore(noreclaim_flag);
>  
>  	if (*compact_result <= COMPACT_INACTIVE)
>  		return NULL;
> @@ -3443,12 +3443,13 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order,
>  {
>  	struct reclaim_state reclaim_state;
>  	int progress;
> +	unsigned int noreclaim_flag;
>  
>  	cond_resched();
>  
>  	/* We now go into synchronous reclaim */
>  	cpuset_memory_pressure_bump();
> -	current->flags |= PF_MEMALLOC;
> +	noreclaim_flag = memalloc_noreclaim_save();
>  	lockdep_set_current_reclaim_state(gfp_mask);
>  	reclaim_state.reclaimed_slab = 0;
>  	current->reclaim_state = &reclaim_state;
> @@ -3458,7 +3459,7 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order,
>  
>  	current->reclaim_state = NULL;
>  	lockdep_clear_current_reclaim_state();
> -	current->flags &= ~PF_MEMALLOC;
> +	memalloc_noreclaim_restore(noreclaim_flag);
>  
>  	cond_resched();
>  
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 58615bb27f2f..ff63b91a0f48 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -2992,6 +2992,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
>  	struct zonelist *zonelist;
>  	unsigned long nr_reclaimed;
>  	int nid;
> +	unsigned int noreclaim_flag;
>  	struct scan_control sc = {
>  		.nr_to_reclaim = max(nr_pages, SWAP_CLUSTER_MAX),
>  		.gfp_mask = (current_gfp_context(gfp_mask) & GFP_RECLAIM_MASK) |
> @@ -3018,9 +3019,9 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
>  					    sc.gfp_mask,
>  					    sc.reclaim_idx);
>  
> -	current->flags |= PF_MEMALLOC;
> +	noreclaim_flag = memalloc_noreclaim_save();
>  	nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
> -	current->flags &= ~PF_MEMALLOC;
> +	memalloc_noreclaim_restore(noreclaim_flag);
>  
>  	trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
>  
> @@ -3544,8 +3545,9 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
>  	struct zonelist *zonelist = node_zonelist(numa_node_id(), sc.gfp_mask);
>  	struct task_struct *p = current;
>  	unsigned long nr_reclaimed;
> +	unsigned int noreclaim_flag;
>  
> -	p->flags |= PF_MEMALLOC;
> +	noreclaim_flag = memalloc_noreclaim_save();
>  	lockdep_set_current_reclaim_state(sc.gfp_mask);
>  	reclaim_state.reclaimed_slab = 0;
>  	p->reclaim_state = &reclaim_state;
> @@ -3554,7 +3556,7 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
>  
>  	p->reclaim_state = NULL;
>  	lockdep_clear_current_reclaim_state();
> -	p->flags &= ~PF_MEMALLOC;
> +	memalloc_noreclaim_restore(noreclaim_flag);
>  
>  	return nr_reclaimed;
>  }
> @@ -3719,6 +3721,7 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in
>  	struct task_struct *p = current;
>  	struct reclaim_state reclaim_state;
>  	int classzone_idx = gfp_zone(gfp_mask);
> +	unsigned int noreclaim_flag;
>  	struct scan_control sc = {
>  		.nr_to_reclaim = max(nr_pages, SWAP_CLUSTER_MAX),
>  		.gfp_mask = (gfp_mask = current_gfp_context(gfp_mask)),
> @@ -3736,7 +3739,8 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in
>  	 * and we also need to be able to write out pages for RECLAIM_WRITE
>  	 * and RECLAIM_UNMAP.
>  	 */
> -	p->flags |= PF_MEMALLOC | PF_SWAPWRITE;
> +	noreclaim_flag = memalloc_noreclaim_save();
> +	p->flags |= PF_SWAPWRITE;
>  	lockdep_set_current_reclaim_state(gfp_mask);
>  	reclaim_state.reclaimed_slab = 0;
>  	p->reclaim_state = &reclaim_state;
> @@ -3752,7 +3756,8 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in
>  	}
>  
>  	p->reclaim_state = NULL;
> -	current->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE);
> +	current->flags &= ~PF_SWAPWRITE;
> +	memalloc_noreclaim_restore(noreclaim_flag);
>  	lockdep_clear_current_reclaim_state();
>  	return sc.nr_reclaimed >= nr_pages;
>  }
> -- 
> 2.12.2

-- 
Michal Hocko
SUSE Labs

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

  parent reply	other threads:[~2017-04-05 11:28 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-05  7:46 [PATCH 0/4] more robust PF_MEMALLOC handling Vlastimil Babka
2017-04-05  7:46 ` [PATCH 2/4] mm: introduce memalloc_noreclaim_{save,restore} Vlastimil Babka
     [not found]   ` <20170405074700.29871-3-vbabka-AlSwsSmVLrQ@public.gmane.org>
2017-04-05 11:28     ` Michal Hocko [this message]
2017-04-07  7:38   ` Hillf Danton
     [not found] ` <20170405074700.29871-1-vbabka-AlSwsSmVLrQ@public.gmane.org>
2017-04-05  7:46   ` [PATCH 1/4] mm: prevent potential recursive reclaim due to clearing PF_MEMALLOC Vlastimil Babka
2017-04-05 11:21     ` Michal Hocko
2017-04-05 11:40     ` Andrey Ryabinin
2017-04-07  9:21       ` Vlastimil Babka
2017-04-07  7:33     ` Hillf Danton
2017-04-05  7:46   ` [PATCH 3/4] treewide: convert PF_MEMALLOC manipulations to new helpers Vlastimil Babka
     [not found]     ` <20170405074700.29871-4-vbabka-AlSwsSmVLrQ@public.gmane.org>
2017-04-05 11:30       ` Michal Hocko
     [not found]         ` <20170405113030.GL6035-2MMpYkNvuYDjFM9bn6wA6Q@public.gmane.org>
2017-04-06  6:38           ` Wouter Verhelst
2017-04-06 11:25             ` [Nbd] " Mel Gorman
2017-04-05  7:47   ` [PATCH 4/4] mtd: nand: nandsim: convert to memalloc_noreclaim_*() Vlastimil Babka
2017-04-05 11:31     ` Michal Hocko
2017-04-05 11:36       ` Richard Weinberger
2017-04-05 11:39         ` Vlastimil Babka
2017-04-05 12:09           ` Michal Hocko
2017-04-06  6:33           ` Adrian Hunter
     [not found]             ` <fe1c21a4-0bc6-529c-5446-382b01d4c99e-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-04-06  7:27               ` Michal Hocko

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=20170405112817.GK6035@dhcp22.suse.cz \
    --to=mhocko-dgejt+ai2ygdnm+yrofe0a@public.gmane.org \
    --cc=akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
    --cc=hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org \
    --cc=linux-block-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org \
    --cc=linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mgorman-3eNAlZScCAx27rWaFMvyedHuzzzSOjJt@public.gmane.org \
    --cc=nbd-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=open-iscsi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    --cc=vbabka-AlSwsSmVLrQ@public.gmane.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