Re: [PATCH v2] dm-crypt: refactor buffer allocation retry handling

Mikulas Patocka <[email protected]>
Newsgroups dev.linux.lists.dm-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

On Tue, 11 Aug 2026, Runyu Xiao wrote:

> crypt_alloc_buffer() conditionally acquires bio_alloc_lock around the
> allocation path and also contains the retry logic for the reclaim
> fallback.
> 
> Move one allocation attempt into crypt_alloc_buffer_try() so that
> bio_alloc_lock is always acquired and released in crypt_alloc_buffer(),
> and the retry decision is made only after the mutex has been dropped.
> 
> This keeps the retry path outside the locked region and makes the
> locking context easier to analyze.
> 
> Signed-off-by: Runyu Xiao <[email protected]>

Hi

I wouldn't do this. The patch just moves code around and increases code 
size with no benefit.

Mikulas

> ---
> Changes in v2:
> - Move one allocation attempt into crypt_alloc_buffer_try(), as suggested
>   by Bart Van Assche.
> - Keep bio_alloc_lock acquisition and release in crypt_alloc_buffer(), and
>   make the retry decision only after releasing the lock.
> - Preserve the distinction between a page-pool retry and a final integrity
>   allocation failure.
> 
> v1: https://lore.kernel.org/r/[email protected]
> 
> diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
> index 608b617fb817..7c68fad12960 100644
> --- a/drivers/md/dm-crypt.c
> +++ b/drivers/md/dm-crypt.c
> @@ -1627,18 +1627,16 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone);
>   * In order to reduce allocation overhead, we try to allocate compound pages in
>   * the first pass. If they are not available, we fall back to the mempool.
>   */
> -static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size)
> +static struct bio *crypt_alloc_buffer_try(struct dm_crypt_io *io,
> +					  unsigned int size, gfp_t gfp_mask,
> +					  unsigned int order, bool *retry)
>  {
>  	struct crypt_config *cc = io->cc;
>  	struct bio *clone;
>  	unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> -	gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM;
>  	unsigned int remaining_size;
> -	unsigned int order = MAX_PAGE_ORDER;
>  
> -retry:
> -	if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM))
> -		mutex_lock(&cc->bio_alloc_lock);
> +	*retry = false;
>  
>  	clone = bio_alloc_bioset(cc->dev->bdev, nr_iovecs, io->base_bio->bi_opf,
>  				 GFP_NOIO, &cc->bs);
> @@ -1674,9 +1672,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size)
>  		if (!pages) {
>  			crypt_free_buffer_pages(cc, clone);
>  			bio_put(clone);
> -			gfp_mask |= __GFP_DIRECT_RECLAIM;
> -			order = 0;
> -			goto retry;
> +			*retry = true;
> +			return NULL;
>  		}
>  
>  have_pages:
> @@ -1692,12 +1689,34 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size)
>  		clone = NULL;
>  	}
>  
> -	if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM))
> -		mutex_unlock(&cc->bio_alloc_lock);
> -
>  	return clone;
>  }
>  
> +static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size)
> +{
> +	struct crypt_config *cc = io->cc;
> +	struct bio *clone;
> +	gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM;
> +	unsigned int order = MAX_PAGE_ORDER;
> +	bool retry;
> +
> +	for (;;) {
> +		if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM))
> +			mutex_lock(&cc->bio_alloc_lock);
> +
> +		clone = crypt_alloc_buffer_try(io, size, gfp_mask, order, &retry);
> +
> +		if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM))
> +			mutex_unlock(&cc->bio_alloc_lock);
> +
> +		if (!retry)
> +			return clone;
> +
> +		gfp_mask |= __GFP_DIRECT_RECLAIM;
> +		order = 0;
> +	}
> +}
> +
>  static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
>  {
>  	struct folio_iter fi;
> -- 
> 2.34.1
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.