On Fri, Feb 16, 2024 at 12:55 AM Chengming Zhou <zhouchengming@xxxxxxxxxxxxx> wrote: > > Dynamic zswap_pool creation may create/reuse to have multiple > zswap_pools in a list, only the first will be current used. > > Each zswap_pool has its own lru and shrinker, which is not > necessary and has its problem: > > 1. When memory has pressure, all shrinker of zswap_pools will > try to shrink its own lru, there is no order between them. > > 2. When zswap limit hit, only the last zswap_pool's shrink_work > will try to shrink its lru list. The rationale here was to > try and empty the old pool first so that we can completely > drop it. However, since we only support exclusive loads now, > the LRU ordering should be entirely decided by the order of > stores, so the oldest entries on the LRU will naturally be > from the oldest pool. > > Anyway, having a global lru and shrinker shared by all zswap_pools > is better and efficient. > > Acked-by: Yosry Ahmed <yosryahmed@xxxxxxxxxx> > Signed-off-by: Chengming Zhou <zhouchengming@xxxxxxxxxxxxx> > --- > mm/zswap.c | 171 ++++++++++++++++++++++++------------------------------------- > 1 file changed, 66 insertions(+), 105 deletions(-) > > diff --git a/mm/zswap.c b/mm/zswap.c > index 62fe307521c9..d275eb523fc4 100644 > --- a/mm/zswap.c > +++ b/mm/zswap.c > @@ -176,14 +176,19 @@ struct zswap_pool { > struct kref kref; > struct list_head list; > struct work_struct release_work; > - struct work_struct shrink_work; > struct hlist_node node; > char tfm_name[CRYPTO_MAX_ALG_NAME]; > +}; > + > +static struct { > struct list_lru list_lru; > - struct mem_cgroup *next_shrink; > - struct shrinker *shrinker; > atomic_t nr_stored; > -}; > + struct shrinker *shrinker; > + struct work_struct shrink_work; > + struct mem_cgroup *next_shrink; > + /* The lock protects next_shrink. */ > + spinlock_t shrink_lock; > +} zswap; nit: Is there a reason why we're putting these in a struct instead of just a bunch of static variables (perhaps prefixed with zswap?)