The BUG is triggered if tcache_get_node is about to return an
invalidated node. This actually can happen if cleancache_get_page races
with cleancache_invalidate_inode as follows, e.g. while concurrent
direct reads/writes are performed:

CPU0                                    CPU1
----                                    ----
cleancache_get_page                     cleancache_invalidate_inode
 tcache_cleancache_get_page              tcache_cleancache_invalidate_inode
  tcache_get_node_and_pool                tcache_invalidate_node
   tcache_get_node
    spin_lock_irqsave(&tree->lock, flags)
    node = <lookup in the tree>
    spin_unlock_irqrestore(&tree->lock, flags)
                                          spin_lock_irq(&tree->lock)
                                          <remove node from the tree>
                                          spin_unlock_irq(&tree->lock)
                                          tcache_invalidate_node_pages
                                           spin_lock_irq(&node->tree_lock)
                                           node->invalidated = true
    BUG_ON(node->invalidated);

Instead of panicking we should drop the page further in
cleancache_get_page.

https://jira.sw.ru/browse/PSBM-34620

Signed-off-by: Vladimir Davydov <vdavy...@parallels.com>
---
 mm/tcache.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mm/tcache.c b/mm/tcache.c
index e83ad05da944..b70fbaeab926 100644
--- a/mm/tcache.c
+++ b/mm/tcache.c
@@ -418,7 +418,6 @@ retry:
 
        if (node) {
                BUG_ON(node->pool != pool);
-               BUG_ON(node->invalidated);
                if (node != new_node)
                        kfree(new_node);
                return node;
@@ -866,6 +865,10 @@ static int tcache_cleancache_get_page(int pool_id,
        node = tcache_get_node_and_pool(pool_id, &key, false);
        if (node) {
                cache_page = tcache_detach_page(node, index);
+               if (unlikely(node->invalidated)) {
+                       put_page(cache_page);
+                       cache_page = NULL;
+               }
                tcache_put_node_and_pool(node);
        }
 
-- 
2.1.4

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to