On Fri, Mar 26, 2021 at 10:55:44PM -0400, Mike Marshall wrote: > Hi David. > > I implemented a version with iov_iter_xarray (below). > It appears to be doing "the right thing" when it > gets called, but then I get a backtrace in the kernel > ring buffer "RIP: 0010:read_pages+0x1a1/0x2c0" which is > page dumped because: VM_BUG_ON_PAGE(!PageLocked(page)) > ------------[ cut here ]------------ > kernel BUG at include/linux/pagemap.h:892! > > So it seems that in mm/readahead.c/read_pages I end up > entering the "Clean up the remaining pages" part, and > never make it through even one iteration... it happens > whether I use readahead_expand or not. > > I've been looking at it a long time :-), I'll look more > tomorrow... do you see anything obvious? Yes; Dave's sample code doesn't consume the pages from the readahead iterator, so the core code thinks you didn't consume them and unlocks / puts the pages for you. That goes wrong, because you did actually consume them. Glad I added the assertions now! We should probably add something like: static inline void readahead_consume(struct readahead_control *ractl, unsigned int nr) { ractl->_nr_pages -= nr; ractl->_index += nr; } to indicate that you consumed the pages other than by calling readahead_page() or readahead_page_batch(). Or maybe Dave can wrap iov_iter_xarray() in a readahead_iter() macro or something that takes care of adjusting index & nr_pages for you.