On 1/7/20 7:06 PM, Damien Le Moal wrote: > On 2020/01/08 10:25, Ming Lei wrote: >> Commit 429120f3df2d starts to take account of segment's start dma address >> when computing max segment size, and data type of 'unsigned long' >> is used to do that. However, the segment mask may be 0xffffffff, so >> the figured out segment size may be overflowed because DMA address can >> be 64bit on 32bit arch. >> >> Fixes the issue by using 'unsigned long long' to compute max segment >> size. >> >> Fixes: 429120f3df2d ("block: fix splitting segments on boundary masks") >> Reported-by: Guenter Roeck <linux@xxxxxxxxxxxx> >> Tested-by: Guenter Roeck <linux@xxxxxxxxxxxx> >> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> >> --- >> block/blk-merge.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/block/blk-merge.c b/block/blk-merge.c >> index 347782a24a35..b0fcc72594cb 100644 >> --- a/block/blk-merge.c >> +++ b/block/blk-merge.c >> @@ -159,12 +159,12 @@ static inline unsigned get_max_io_size(struct request_queue *q, >> >> static inline unsigned get_max_segment_size(const struct request_queue *q, >> struct page *start_page, >> - unsigned long offset) >> + unsigned long long offset) >> { >> unsigned long mask = queue_segment_boundary(q); >> >> offset = mask & (page_to_phys(start_page) + offset); > > Shouldn't mask be an unsigned long long too for this to give the > expected correct result ? Don't think so, and the seg boundary is a ulong to begin with as well. -- Jens Axboe