Hi

On Mon, 16 Mar 2026, Keith Busch wrote:

> From: Keith Busch <[email protected]>
> 
> Many storage devices can handle DMA for data that is not aligned to the
> sector block size. The block and filesystem layers have introduced
> updates to allow that kind of memory alignment flexibility when
> possible.
> 
> dm-crypt, however, currently constrains itself to aligned memory because
> it sends a single scatterlist element for the in/out list to the encrypt
> and decrypt algorithms. This forces applications that have unaligned
> data to copy through a bounce buffer, increasing CPU and memory
> utilization.
> 
> Use multiple scatterlist elements to relax the memory alignment
> requirement. To keep this simple, this more flexible constraint is
> enabled only for certain encryption and initialization vector types,
> specifically the ones that don't have additional use for the request
> base scatterlist elements beyond holding decrypted data.
> 
> Signed-off-by: Keith Busch <[email protected]>
>  
> +     if (!unaligned_allowed) {
> +             cc->io_alignment = cc->sector_size - 1;
> +     } else {
> +             set_bit(CRYPT_DISCONTIGUOUS_SEGS, &cc->cipher_flags);
> +             cc->io_alignment = 3;
> +     }
>       return 0;
>  }

Why is "3" there? Should there be the dma_alignment of the underlying 
block device instead?

> @@ -3722,7 +3761,11 @@ static void crypt_io_hints(struct dm_target *ti, 
> struct queue_limits *limits)
>       limits->physical_block_size =
>               max_t(unsigned int, limits->physical_block_size, 
> cc->sector_size);
>       limits->io_min = max_t(unsigned int, limits->io_min, cc->sector_size);
> -     limits->dma_alignment = limits->logical_block_size - 1;
> +
> +     if (test_bit(CRYPT_DISCONTIGUOUS_SEGS, &cc->cipher_flags))
> +             limits->dma_alignment = cc->io_alignment;
> +     else
> +             limits->dma_alignment = limits->logical_block_size - 1;
>  
>       /*
>        * For zoned dm-crypt targets, there will be no internal splitting of
> diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
> index dc2eff6b739df..aecb19a6913db 100644
> --- a/drivers/md/dm-table.c
> +++ b/drivers/md/dm-table.c
> @@ -1767,6 +1767,7 @@ int dm_calculate_queue_limits(struct dm_table *t,
>       bool zoned = false;
>  
>       dm_set_stacking_limits(limits);
> +     limits->dma_alignment = 0;
>  
>       t->integrity_supported = true;
>       for (unsigned int i = 0; i < t->num_targets; i++) {

dm-integrity doesn't set dma_alignment if it is using 512-byte sector size 
(assuming that there is default 511). This should be fixed in dm-integrity 
before making this change.

Other device mapper targets should also be reviewed to make sure that this 
change doens't break them.

Mikulas


Reply via email to