tcache_invalidate_node_pages() temporarly drops/takes back node->tree_lock.
Once lock was dropped, we can't continue iterating to the next slot, because
another thread might remove and free it. If lock was dropped tree iteration
has to be restarted.
Wit this patch we also drop the lock iff we need to resched the task.

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

Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
---
 mm/tcache.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/mm/tcache.c b/mm/tcache.c
index b8757cf..a09ae49 100644
--- a/mm/tcache.c
+++ b/mm/tcache.c
@@ -662,6 +662,7 @@ tcache_invalidate_node_pages(struct tcache_node *node)
        struct radix_tree_iter iter;
        struct page *page;
        void **slot;
+       pgoff_t index = 0;
 
        spin_lock_irq(&node->tree_lock);
 
@@ -674,19 +675,25 @@ tcache_invalidate_node_pages(struct tcache_node *node)
         * Now truncate all pages. Be careful, because pages can still be
         * deleted from this node by the shrinker or by concurrent lookups.
         */
-       radix_tree_for_each_slot(slot, &node->page_tree, &iter, 0) {
+restart:
+       radix_tree_for_each_slot(slot, &node->page_tree, &iter, index) {
                page = radix_tree_deref_slot_protected(slot, &node->tree_lock);
                BUG_ON(!__tcache_page_tree_delete(node, page->index, page));
-               spin_unlock(&node->tree_lock);
-
                tcache_lru_del(page);
                put_page(page);
 
-               local_irq_enable();
-               cond_resched();
-               local_irq_disable();
-
-               spin_lock(&node->tree_lock);
+               if (need_resched()) {
+                       spin_unlock_irq(&node->tree_lock);
+                       cond_resched();
+                       spin_lock_irq(&node->tree_lock);
+                       /*
+                        * Restart iteration over the radix tree, because the
+                        * current node could have been freed when we dropped
+                        * the lock.
+                        */
+                       index = page->index + 1;
+                       goto restart;
+               }
        }
 
        BUG_ON(node->nr_pages != 0);
-- 
2.4.10

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

Reply via email to