On Thu 17-11-16 14:11:32, Johannes Weiner wrote:
> When the shadow page shrinker tries to reclaim a radix tree node but
> finds it in an unexpected state - it should contain no pages, and
> non-zero shadow entries - there is no need to kill the executing task
> or even the entire system. Warn about the invalid state, then leave
> that tree node be. Simply don't put it back on the shadow LRU for
> future reclaim and move on.
> 
> Signed-off-by: Johannes Weiner <han...@cmpxchg.org>

Looks good. You can add:

Reviewed-by: Jan Kara <j...@suse.cz>

                                                                Honza

> ---
>  mm/workingset.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/mm/workingset.c b/mm/workingset.c
> index 617475f529f4..3cfc61d84a52 100644
> --- a/mm/workingset.c
> +++ b/mm/workingset.c
> @@ -418,23 +418,27 @@ static enum lru_status shadow_lru_isolate(struct 
> list_head *item,
>        * no pages, so we expect to be able to remove them all and
>        * delete and free the empty node afterwards.
>        */
> -     BUG_ON(!workingset_node_shadows(node));
> -     BUG_ON(workingset_node_pages(node));
> -
> +     if (WARN_ON_ONCE(!workingset_node_shadows(node)))
> +             goto out_invalid;
> +     if (WARN_ON_ONCE(workingset_node_pages(node)))
> +             goto out_invalid;
>       for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) {
>               if (node->slots[i]) {
> -                     BUG_ON(!radix_tree_exceptional_entry(node->slots[i]));
> +                     if 
> (WARN_ON_ONCE(!radix_tree_exceptional_entry(node->slots[i])))
> +                             goto out_invalid;
> +                     if (WARN_ON_ONCE(!mapping->nrexceptional))
> +                             goto out_invalid;
>                       node->slots[i] = NULL;
>                       workingset_node_shadows_dec(node);
> -                     BUG_ON(!mapping->nrexceptional);
>                       mapping->nrexceptional--;
>               }
>       }
> -     BUG_ON(workingset_node_shadows(node));
> +     if (WARN_ON_ONCE(workingset_node_shadows(node)))
> +             goto out_invalid;
>       inc_node_state(page_pgdat(virt_to_page(node)), WORKINGSET_NODERECLAIM);
> -     if (!__radix_tree_delete_node(&mapping->page_tree, node))
> -             BUG();
> +     __radix_tree_delete_node(&mapping->page_tree, node);
>  
> +out_invalid:
>       spin_unlock(&mapping->tree_lock);
>       ret = LRU_REMOVED_RETRY;
>  out:
> -- 
> 2.10.2
> 
-- 
Jan Kara <j...@suse.com>
SUSE Labs, CR

Reply via email to