On Sat, Dec 03, 2022 at 01:44:20AM +0300, Mikhail Pletnev wrote: > On Fri, 2 Dec 2022 21:57:09 +0000 > Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > > On Fri, Dec 02, 2022 at 04:58:42PM +0000, Matthew Wilcox wrote: > > > Landing on 793917d997df makes a lot more sense. That's where we > > > actually start using large folios. It doesn't really help narrow > > > down the problem. I have an idea for what it might be; patch to > > > try will follow. But I'll need feedback by email. > > > > This will give us a bit more information when it does happen. > > Further patch to catch it earlier will come "soon". > > > > diff --git a/lib/xarray.c b/lib/xarray.c > > index 6f47f6375808..b358b4e1dac6 100644 > > --- a/lib/xarray.c > > +++ b/lib/xarray.c > > @@ -6,6 +6,7 @@ > > * Author: Matthew Wilcox <willy@xxxxxxxxxxxxx> > > */ > > > > +#define XA_DEBUG > > #include <linux/bitmap.h> > > #include <linux/export.h> > > #include <linux/list.h> > > @@ -207,6 +208,12 @@ static void *xas_descend(struct xa_state *xas, struct xa_node *node) > > if (xa_is_sibling(entry)) { > > offset = xa_to_sibling(entry); > > entry = xa_entry(xas->xa, node, offset); > > + > > + if (xa_is_sibling(entry)) { > > + printk("***BAD SIBLING*** index %ld offset %d\n", > > + xas->xa_index, offset); > > + xa_dump_node(node); > > + } > > } > > > > xas->xa_offset = offset; > > here is the crash with your patch (full dmesg in attachement): Thanks! I think this may be the problem ... diff --git a/include/linux/xarray.h b/include/linux/xarray.h index 44dd6d6e01bc..cc1fd1f849a7 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -1617,6 +1617,12 @@ static inline void xas_advance(struct xa_state *xas, unsigned long index) xas->xa_offset = (index >> shift) & XA_CHUNK_MASK; } +static inline void xas_adjust_order(struct xa_state *xas, unsigned int order) +{ + xas->xa_shift = order - (order % XA_CHUNK_SHIFT); + xas->xa_sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; +} + /** * xas_set_order() - Set up XArray operation state for a multislot entry. * @xas: XArray operation state. @@ -1628,8 +1634,7 @@ static inline void xas_set_order(struct xa_state *xas, unsigned long index, { #ifdef CONFIG_XARRAY_MULTI xas->xa_index = order < BITS_PER_LONG ? (index >> order) << order : 0; - xas->xa_shift = order - (order % XA_CHUNK_SHIFT); - xas->xa_sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; + xas_adjust_order(xas, order); xas->xa_node = XAS_RESTART; #else BUG_ON(order > 0); diff --git a/mm/filemap.c b/mm/filemap.c index 08341616ae7a..6e3f486131e4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -305,11 +305,13 @@ static void page_cache_delete_batch(struct address_space *mapping, WARN_ON_ONCE(!folio_test_locked(folio)); + if (!folio_test_hugetlb(folio)) + xas_adjust_order(&xas, folio_order(folio)); + xas_store(&xas, NULL); folio->mapping = NULL; /* Leave folio->index set: truncation lookup relies on it */ i++; - xas_store(&xas, NULL); total_pages += folio_nr_pages(folio); } mapping->nrpages -= total_pages;