workingset: memcg: sleep when flushing stats in workingset_refault()
[linux-block.git] / mm / workingset.c
index dab0c362b9e3d6b4039d45a980e09a0795bc6456..3025beee9b3441d96968fda41d68a1d0938442ff 100644 (file)
@@ -406,6 +406,9 @@ void workingset_refault(struct folio *folio, void *shadow)
        unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset);
        eviction <<= bucket_order;
 
+       /* Flush stats (and potentially sleep) before holding RCU read lock */
+       mem_cgroup_flush_stats_ratelimited();
+
        rcu_read_lock();
        /*
         * Look up the memcg associated with the stored ID. It might
@@ -461,8 +464,6 @@ void workingset_refault(struct folio *folio, void *shadow)
        lruvec = mem_cgroup_lruvec(memcg, pgdat);
 
        mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + file, nr);
-
-       mem_cgroup_flush_stats_atomic_ratelimited();
        /*
         * Compare the distance to the existing workingset size. We
         * don't activate pages that couldn't stay resident even if