Currently the following race between page attach and invalidate page could result in crashes:
CPU1 CPU2 tcache_cleancache_put_page(); tcache_attach_page(); tcache_page_tree_replace(); tcache_invalidate_node_pages(); page = radix_tree_deref_slot_protected(); __tcache_page_tree_delete(page); tcache_lru_del(page); tcache_put_page(page); <-- this frees the page ... tcache_hold_page(page); // page may freed at this point tcache_lru_add(node->pool, page); To prevent this, protect with node->tree_lock not only insertion to radix tree, but also tcache_hold_page() and addition to the lru list. So if we extract the page from radix_tree now we can be sure that it is already on lru list and page refcounter increased. https://jira.sw.ru/browse/PSBM-63197 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> --- mm/tcache.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mm/tcache.c b/mm/tcache.c index c7613b2..e15d212 100644 --- a/mm/tcache.c +++ b/mm/tcache.c @@ -724,7 +724,6 @@ static int tcache_page_tree_replace(struct tcache_node *node, pgoff_t index, *old_page = NULL; - spin_lock(&node->tree_lock); /* * If the node was invalidated after we looked it up, abort in order to * avoid clashes with tcache_invalidate_node_pages. @@ -752,7 +751,6 @@ static int tcache_page_tree_replace(struct tcache_node *node, pgoff_t index, } } out: - spin_unlock(&node->tree_lock); return err; } @@ -792,7 +790,7 @@ tcache_attach_page(struct tcache_node *node, pgoff_t index, struct page *page) tcache_init_page(page, node, index); - local_irq_save(flags); + spin_lock_irqsave(&node->tree_lock, flags); err = tcache_page_tree_replace(node, index, page, &old_page); if (err) goto out; @@ -804,7 +802,7 @@ tcache_attach_page(struct tcache_node *node, pgoff_t index, struct page *page) tcache_hold_page(page); tcache_lru_add(node->pool, page); out: - local_irq_restore(flags); + spin_unlock_irqrestore(&node->tree_lock, flags); return err; } -- 2.10.2 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel