[Devel] [PATCH] tcache: Repeat invalidation in tcache_invalidate_node_pages()
Kirill Tkhai
ktkhai at virtuozzo.com
Thu Nov 30 19:22:06 MSK 2017
tcache_shrink_scan() tcache_destroy_pool
tcache_lru_isolate()
tcache_grab_pool()
...
page_cache_get_speculative() -->cnt == 2
...
tcache_put_pool() --> pool cnt zero
... wait_for_completion(&pool->completion);
tcache_reclaim_pages tcache_invalidate_node_pages()
__tcache_reclaim_page() tcache_lookup()
page_cache_get_speculative --> cnt == 3
__tcache_page_tree_delete
page_ref_freeze(2) -->fail page_ref_freeze(2) -->fail
On 30.11.2017 19:02, Kirill Tkhai wrote:
> When there are more than 2 users of a page, __tcache_page_tree_delete()
> fails to freeze it. We skip it and never try to freeze the page again.
>
> In this case the page remains not invalidated, and tcache_node->nr_pages
> never decremented. Later, we catch WARN_ON() reporting about this.
>
> The patch fixes the problem. In case of we failed to invalidate a page,
> we remember that, and return to such pages after others are invalidated.
>
> https://jira.sw.ru/browse/PSBM-78354
>
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
> mm/tcache.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/mm/tcache.c b/mm/tcache.c
> index d1a2c53e11a..cbc50d4b8bc 100644
> --- a/mm/tcache.c
> +++ b/mm/tcache.c
> @@ -903,13 +903,15 @@ tcache_invalidate_node_pages(struct tcache_node *node)
> struct page *pages[TCACHE_PAGEVEC_SIZE];
> pgoff_t index = 0;
> unsigned nr_pages;
> + bool repeat;
> int i;
>
> /*
> * First forbid new page insertions - see tcache_page_tree_replace.
> */
> node->invalidated = true;
> -
> +again:
> + repeat = false;
> while ((nr_pages = tcache_lookup(pages, node, index,
> TCACHE_PAGEVEC_SIZE, indices))) {
> for (i = 0; i < nr_pages; i++) {
> @@ -925,13 +927,20 @@ tcache_invalidate_node_pages(struct tcache_node *node)
> tcache_lru_del(node->pool, page, false);
> local_irq_enable();
> tcache_put_page(page);
> - } else
> + } else {
> local_irq_enable();
> + repeat = true;
> + }
> }
> cond_resched();
> index++;
> }
>
> + if (repeat) {
> + index = 0;
> + goto again;
> + }
> +
> WARN_ON(node->nr_pages != 0);
> }
>
>
More information about the Devel
mailing list