On Mon, Nov 27, 2023 at 03:45:57PM -0800, Nhat Pham wrote: > static void shrink_worker(struct work_struct *w) > { > struct zswap_pool *pool = container_of(w, typeof(*pool), > shrink_work); > + struct mem_cgroup *memcg; > int ret, failures = 0; > > + /* global reclaim will select cgroup in a round-robin fashion. */ > do { > - ret = zswap_reclaim_entry(pool); > - if (ret) { > - zswap_reject_reclaim_fail++; > - if (ret != -EAGAIN) > - break; > + spin_lock(&zswap_pools_lock); > + memcg = pool->next_shrink = > + mem_cgroup_iter_online(NULL, pool->next_shrink, NULL, true); > + > + /* full round trip */ > + if (!memcg) { > + spin_unlock(&zswap_pools_lock); > if (++failures == MAX_RECLAIM_RETRIES) > break; > + > + goto resched; > } > + > + /* > + * Acquire an extra reference to the iterated memcg in case the > + * original reference is dropped by the zswap offlining callback. > + */ > + css_get(&memcg->css); struct mem_cgroup isn't defined when !CONFIG_MEMCG. This needs a mem_cgroup_get() wrapper and a dummy function for no-memcg builds. With that fixed, though, everything else looks good to me: Acked-by: Johannes Weiner <hannes@xxxxxxxxxxx>