On Wed, Jan 08, 2020 at 06:30:35AM +0800, Ming Lei wrote: > On Tue, Jan 07, 2020 at 10:11:45AM -0800, Guenter Roeck wrote: > > On Tue, Jan 07, 2020 at 11:23:39PM +0800, Ming Lei wrote: > > > On Tue, Jan 07, 2020 at 04:47:08AM -0800, Guenter Roeck wrote: > > > > Hi, > > > > > > > > On Sun, Dec 29, 2019 at 10:32:30AM +0800, Ming Lei wrote: > > > > > There are two issues in get_max_segment_size(): > > > > > > > > > > 1) the default segment boudary mask is bypassed, and some devices still > > > > > require segment to not cross the default 4G boundary > > > > > > > > > > 2) the segment start address isn't taken into account when checking > > > > > segment boundary limit > > > > > > > > > > Fixes the two issues. > > > > > > > > > > Fixes: dcebd755926b ("block: use bio_for_each_bvec() to compute multi-page bvec count") > > > > > Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> > > > > > > > > This patch, pushed into mainline as "block: fix splitting segments on > > > > boundary masks", results in the following crash when booting 'versatilepb' > > > > in qemu from disk. Bisect log is attached. Detailed log is at > > > > https://kerneltests.org/builders/qemu-arm-master/builds/1410/steps/qemubuildcommand/logs/stdio > > > > > > > > Guenter > > > > > > > > --- > > > > Crash: > > > > > > > > kernel BUG at block/bio.c:1885! > > > > Internal error: Oops - BUG: 0 [#1] ARM > > > > > > Please apply the following debug patch, and post the log. > > > > > > > Here you are: > > > > max_sectors 2560 max_segs 96 max_seg_size 65536 mask ffffffff > > c738da80: 8c80/0 2416 28672, 0 > > total sectors 56 > > > > (I replaced %p with %px). > > > > Please try the following patch and see if it makes a difference. > If not, replace trace_printk with printk in previous debug patch, > and apply the debug patch only & post the log. > The patch below fixes the problem for me. Tested-by: Guenter Roeck <linux@xxxxxxxxxxxx> Guenter > diff --git a/block/blk-merge.c b/block/blk-merge.c > index 347782a24a35..f152bdee9b05 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); > - return min_t(unsigned long, mask - offset + 1, > + return min_t(unsigned long long, mask - offset + 1, > queue_max_segment_size(q)); > } > > > Thanks, > Ming >