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 ? > - return min_t(unsigned long, mask - offset + 1, > + return min_t(unsigned long long, mask - offset + 1, > queue_max_segment_size(q)); > } > > -- Damien Le Moal Western Digital Research