On Tue, 9 Oct 2018 14:47:32 -0400 Johannes Weiner <hannes@xxxxxxxxxxx> wrote: > --- a/mm/workingset.c > +++ b/mm/workingset.c > @@ -378,11 +378,17 @@ void workingset_update_node(struct xa_node *node) > * as node->private_list is protected by the i_pages lock. > */ > if (node->count && node->count == node->nr_values) { > - if (list_empty(&node->private_list)) > + if (list_empty(&node->private_list)) { > list_lru_add(&shadow_nodes, &node->private_list); > + __inc_lruvec_page_state(virt_to_page(node), > + WORKINGSET_NODES); > + } > } else { > - if (!list_empty(&node->private_list)) > + if (!list_empty(&node->private_list)) { > list_lru_del(&shadow_nodes, &node->private_list); > + __dec_lruvec_page_state(virt_to_page(node), > + WORKINGSET_NODES); > + } > } > } A bit worried that we're depending on the caller's caller to have disabled interrupts to avoid subtle and rare errors. Can we do this? --- a/mm/workingset.c~mm-workingset-add-vmstat-counter-for-shadow-nodes-fix +++ a/mm/workingset.c @@ -377,6 +377,8 @@ void workingset_update_node(struct radix * already where they should be. The list_empty() test is safe * as node->private_list is protected by the i_pages lock. */ + WARN_ON_ONCE(!irqs_disabled()); /* For __inc_lruvec_page_state */ + if (node->count && node->count == node->exceptional) { if (list_empty(&node->private_list)) { list_lru_add(&shadow_nodes, &node->private_list); _