On Tue, Nov 22, 2022 at 11:15:20AM +0900, Sergey Senozhatsky wrote: > On (22/11/18 16:15), Nhat Pham wrote: > > + > > +static int zs_zpool_shrink(void *pool, unsigned int pages, > > + unsigned int *reclaimed) > > +{ > > + unsigned int total = 0; > > + int ret = -EINVAL; > > + > > + while (total < pages) { > > + ret = zs_reclaim_page(pool, 8); > > + if (ret < 0) > > + break; > > + total++; > > + } > > + > > + if (reclaimed) > > + *reclaimed = total; > > + > > + return ret; > > +} > > A silly question: why do we need a retry loop in zs_reclaim_page()? Individual objects in a zspage can be busy (swapped in simultaneously for example), which will prevent the zspage from being freed. Zswap currently requests reclaim of one backend page at a time (another project...), so if we don't retry we're not meeting the reclaim goal and cause rejections for new stores. Rejections are worse than moving on to the adjacent LRU item, because a rejected page, which should be at the head of the LRU, bypasses the list and goes straight to swap. The number 8 is cribbed from zbud and z3fold. It works well in practice, but is as arbitrary as MAX_RECLAIM_RETRIES used all over MM. We may want to revisit it at some point, but we should probably do it for all backends then.