[PATCH 04/65] mm: Extract might_alloc() debug check

Paul E. McKenney paulmck at kernel.org
Fri Oct 23 20:53:38 UTC 2020


On Fri, Oct 23, 2020 at 02:21:15PM +0200, Daniel Vetter wrote:
> Extracted from slab.h, which seems to have the most complete version
> including the correct might_sleep() check. Roll it out to slob.c.
> 
> Motivated by a discussion with Paul about possibly changing call_rcu
> behaviour to allocate memory, but only roughly every 500th call.
> 
> There are a lot fewer places in the kernel that care about whether
> allocating memory is allowed or not (due to deadlocks with reclaim
> code) than places that care whether sleeping is allowed. But debugging
> these also tends to be a lot harder, so nice descriptive checks could
> come in handy. I might have some use eventually for annotations in
> drivers/gpu.
> 
> Note that unlike fs_reclaim_acquire/release gfpflags_allow_blocking
> does not consult the PF_MEMALLOC flags. But there is no flag
> equivalent for GFP_NOWAIT, hence this check can't go wrong due to
> memalloc_no*_save/restore contexts.
> 
> Cc: Paul E. McKenney <paulmck at kernel.org>
> Cc: Christoph Lameter <cl at linux.com>
> Cc: Pekka Enberg <penberg at kernel.org>
> Cc: David Rientjes <rientjes at google.com>
> Cc: Joonsoo Kim <iamjoonsoo.kim at lge.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at kernel.org>
> Cc: Vlastimil Babka <vbabka at suse.cz>
> Cc: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> Cc: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> Cc: Michel Lespinasse <walken at google.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Waiman Long <longman at redhat.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Randy Dunlap <rdunlap at infradead.org>
> Cc: linux-mm at kvack.org
> Cc: linux-fsdevel at vger.kernel.org
> Cc: Dave Chinner <david at fromorbit.com>
> Cc: Qian Cai <cai at lca.pw>
> Cc: linux-xfs at vger.kernel.org
> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>

Nice!!!

Acked-by: Paul E. McKenney <paulmck at kernel.org>

> ---
>  include/linux/sched/mm.h | 16 ++++++++++++++++
>  mm/slab.h                |  5 +----
>  mm/slob.c                |  6 ++----
>  3 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
> index f889e332912f..2b0037abac0b 100644
> --- a/include/linux/sched/mm.h
> +++ b/include/linux/sched/mm.h
> @@ -205,6 +205,22 @@ static inline void fs_reclaim_acquire(gfp_t gfp_mask) { }
>  static inline void fs_reclaim_release(gfp_t gfp_mask) { }
>  #endif
>  
> +/**
> + * might_alloc - Marks possible allocation sites
> + * @gfp_mask: gfp_t flags that would be use to allocate
> + *
> + * Similar to might_sleep() and other annotations this can be used in functions
> + * that might allocate, but often dont. Compiles to nothing without
> + * CONFIG_LOCKDEP. Includes a conditional might_sleep() if @gfp allows blocking.
> + */
> +static inline void might_alloc(gfp_t gfp_mask)
> +{
> +	fs_reclaim_acquire(gfp_mask);
> +	fs_reclaim_release(gfp_mask);
> +
> +	might_sleep_if(gfpflags_allow_blocking(gfp_mask));
> +}
> +
>  /**
>   * memalloc_noio_save - Marks implicit GFP_NOIO allocation scope.
>   *
> diff --git a/mm/slab.h b/mm/slab.h
> index 6cc323f1313a..fedd789b2270 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -492,10 +492,7 @@ static inline struct kmem_cache *slab_pre_alloc_hook(struct kmem_cache *s,
>  {
>  	flags &= gfp_allowed_mask;
>  
> -	fs_reclaim_acquire(flags);
> -	fs_reclaim_release(flags);
> -
> -	might_sleep_if(gfpflags_allow_blocking(flags));
> +	might_alloc(flags);
>  
>  	if (should_failslab(s, flags))
>  		return NULL;
> diff --git a/mm/slob.c b/mm/slob.c
> index 7cc9805c8091..8d4bfa46247f 100644
> --- a/mm/slob.c
> +++ b/mm/slob.c
> @@ -474,8 +474,7 @@ __do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller)
>  
>  	gfp &= gfp_allowed_mask;
>  
> -	fs_reclaim_acquire(gfp);
> -	fs_reclaim_release(gfp);
> +	might_alloc(gfp);
>  
>  	if (size < PAGE_SIZE - minalign) {
>  		int align = minalign;
> @@ -597,8 +596,7 @@ static void *slob_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
>  
>  	flags &= gfp_allowed_mask;
>  
> -	fs_reclaim_acquire(flags);
> -	fs_reclaim_release(flags);
> +	might_alloc(flags);
>  
>  	if (c->size < PAGE_SIZE) {
>  		b = slob_alloc(c->size, flags, c->align, node, 0);
> -- 
> 2.28.0
> 


More information about the dri-devel mailing list