]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
XArray: Update the LRU list in xas_split()
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 31 Mar 2022 12:27:09 +0000 (08:27 -0400)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 20 May 2022 13:19:34 +0000 (15:19 +0200)
BugLink: https://bugs.launchpad.net/bugs/1971497
commit 3ed4bb77156da0bc732847c8c9df92454c1fbeea upstream.

When splitting a value entry, we may need to add the new nodes to the LRU
list and remove the parent node from the LRU list.  The WARN_ON checks
in shadow_lru_isolate() catch this oversight.  This bug was latent
until we stopped splitting folios in shrink_page_list() with commit
820c4e2e6f51 ("mm/vmscan: Free non-shmem folios without splitting them").
That allows the creation of large shadow entries, and subsequently when
trying to page in a small page, we will split the large shadow entry
in __filemap_add_folio().

Fixes: 8fc75643c5e1 ("XArray: add xas_split")
Reported-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
lib/xarray.c

index 6a2ad7451bdd7255c24ef08df0b4890b45f814b8..61464c52c20e69b63add12fc7d8a8445cfdd38b3 100644 (file)
@@ -1080,6 +1080,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
                                        xa_mk_node(child));
                        if (xa_is_value(curr))
                                values--;
+                       xas_update(xas, child);
                } else {
                        unsigned int canon = offset - xas->xa_sibs;
 
@@ -1094,6 +1095,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
        } while (offset-- > xas->xa_offset);
 
        node->nr_values += values;
+       xas_update(xas, node);
 }
 EXPORT_SYMBOL_GPL(xas_split);
 #endif