On Mon, Sep 25, 2023 at 01:17:04PM -0700, Yosry Ahmed wrote: > On Tue, Sep 19, 2023 at 10:14 AM Nhat Pham <nphamcs@xxxxxxxxx> wrote: > > + is_empty = false; > > + } > > + zswap_pool_put(pool); > > + > > + if (is_empty) > > + return -EINVAL; > > + if (shrunk) > > + return 0; > > + return -EAGAIN; > > } > > > > static void shrink_worker(struct work_struct *w) > > { > > struct zswap_pool *pool = container_of(w, typeof(*pool), > > shrink_work); > > - int ret, failures = 0; > > + int ret, failures = 0, memcg_selection_failures = 0; > > > > + /* global reclaim will select cgroup in a round-robin fashion. */ > > do { > > - ret = zswap_reclaim_entry(pool); > > + /* previous next_shrink has become a zombie - restart from the top */ > > Do we skip zombies because all zswap entries are reparented with the objcg? > > If yes, why do we restart from the top instead of just skipping them? > memcgs after a zombie will not be reachable now IIUC. > > Also, why explicitly check for zombies instead of having > shrink_memcg() just skip memcgs with no zswap entries? The logic is > slightly complicated. I think this might actually be a leftover from the initial plan to do partial walks without holding on to a reference to the last scanned css. Similar to mem_cgroup_iter() does with the reclaim cookie - if a dead cgroup is encountered and we lose the tree position, restart. But now the code actually holds a reference, so I agree the zombie thing should just be removed.