> > > On a different note, I wonder if it would help to perform synchronous > > > reclaim here instead. With our current design, the zswap store failure > > > (due to global limit hit) would leave the incoming page going to swap > > > instead, creating an LRU inversion. Not sure if that's ideal. > > > > The global shrink path keeps reclaiming until zswap can accept again > > (by default, that means reclaiming 10% of the total limit). I think > > this is too expensive to be done synchronously. > > That thresholding code is a bit weird right now. > > It wakes the shrinker and rejects at the same time. We're guaranteed > to see rejections, even if the shrinker has no trouble flushing some > entries a split second later. > > It would make more sense to wake the shrinker at e.g. 95% full and > have it run until 90%. > > But with that in place we also *should* do synchronous reclaim once we > hit 100%. Just enough to make room for the store. This is important to > catch the case where reclaim rate exceeds swapout rate. Rejecting and > going to swap means the reclaimer will be throttled down to IO rate > anyway, and the app latency isn't any worse. But this way we keep the > pipeline alive, and keep swapping out the oldest zswap entries, > instead of rejecting and swapping what would be the hottest ones. I fully agree with the thresholding code being weird, and with waking up the shrinker before the pool is full. What I don't understand is how we can do synchronous reclaim when we hit 100% and still respect the acceptance threshold :/ Are you proposing we change the semantics of the acceptance threshold to begin with?