summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2025-10-20 14:48:13 +0200
committerMikulas Patocka <mpatocka@redhat.com>2025-12-10 19:28:22 +0100
commitd0ac06ae53be0cdb61f5fe6b62d25d3317c51657 (patch)
tree8ed71307df50056811081721f42f6de5c5791492
parentce51c6963a91cc6d5c9cf6c3735991882f72587d (diff)
dm-bufio: align write boundary on physical block size
There may be devices with physical block size larger than 4k. If dm-bufio sends I/O that is not aligned on physical block size, performance is degraded. The 4k minimum alignment limit is there because some SSDs report logical and physical block size 512 despite having 4k internally - so dm-bufio shouldn't send I/Os not aligned on 4k boundary, because they perform badly (the SSD does read-modify-write for them). Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Reported-by: Uladzislau Rezki (Sony) <urezki@gmail.com> Cc: stable@vger.kernel.org
-rw-r--r--drivers/md/dm-bufio.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index e6d28be11c5c..5235f3e4924b 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -1374,7 +1374,7 @@ static void submit_io(struct dm_buffer *b, enum req_op op, unsigned short ioprio
{
unsigned int n_sectors;
sector_t sector;
- unsigned int offset, end;
+ unsigned int offset, end, align;
b->end_io = end_io;
@@ -1388,9 +1388,11 @@ static void submit_io(struct dm_buffer *b, enum req_op op, unsigned short ioprio
b->c->write_callback(b);
offset = b->write_start;
end = b->write_end;
- offset &= -DM_BUFIO_WRITE_ALIGN;
- end += DM_BUFIO_WRITE_ALIGN - 1;
- end &= -DM_BUFIO_WRITE_ALIGN;
+ align = max(DM_BUFIO_WRITE_ALIGN,
+ bdev_physical_block_size(b->c->bdev));
+ offset &= -align;
+ end += align - 1;
+ end &= -align;
if (unlikely(end > b->c->block_size))
end = b->c->block_size;