On 8/3/24 3:02 AM, Vishal Moola wrote: > On Mon, Jul 29, 2024 at 07:25:14PM +0800, alexs@xxxxxxxxxx wrote: >> From: Alex Shi <alexs@xxxxxxxxxx> >> >> To use zpdesc in trylock_zspage/lock_zspage funcs, we add couple of helpers: >> zpdesc_lock/zpdesc_unlock/zpdesc_trylock/zpdesc_wait_locked and >> zpdesc_get/zpdesc_put for this purpose. > > You should always include the "()" following function names. It just > makes everything more readable. Thanks for reminder, I will update the commit log. > >> Here we use the folio series func in guts for 2 reasons, one zswap.zpool >> only get single page, and use folio could save some compound_head checking; >> two, folio_put could bypass devmap checking that we don't need. >> >> Originally-by: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> >> Signed-off-by: Alex Shi <alexs@xxxxxxxxxx> >> --- >> mm/zpdesc.h | 30 ++++++++++++++++++++++++ >> mm/zsmalloc.c | 64 ++++++++++++++++++++++++++++++++++----------------- >> 2 files changed, 73 insertions(+), 21 deletions(-) >> >> diff --git a/mm/zpdesc.h b/mm/zpdesc.h >> index 2dbef231f616..3b04197cec9d 100644 >> --- a/mm/zpdesc.h >> +++ b/mm/zpdesc.h >> @@ -63,4 +63,34 @@ static_assert(sizeof(struct zpdesc) <= sizeof(struct page)); >> const struct page *: (const struct zpdesc *)(p), \ >> struct page *: (struct zpdesc *)(p))) >> >> +static inline void zpdesc_lock(struct zpdesc *zpdesc) >> +{ >> + folio_lock(zpdesc_folio(zpdesc)); >> +} >> + >> +static inline bool zpdesc_trylock(struct zpdesc *zpdesc) >> +{ >> + return folio_trylock(zpdesc_folio(zpdesc)); >> +} >> + >> +static inline void zpdesc_unlock(struct zpdesc *zpdesc) >> +{ >> + folio_unlock(zpdesc_folio(zpdesc)); >> +} >> + >> +static inline void zpdesc_wait_locked(struct zpdesc *zpdesc) >> +{ >> + folio_wait_locked(zpdesc_folio(zpdesc)); >> +} > > The more I look at zsmalloc, the more skeptical I get about it "needing" > the folio_lock. At a glance it seems like a zspage already has its own lock, > and the migration doesn't appear to be truly physical? There's probably > something I'm missing... it would make this code a lot simpler to drop > many of the folio locks. folio series could save about 6.3% object code... Anyway I don't insist on it. Just want a double confirm, could we keep the code size saving? :) > >> + >> +static inline void zpdesc_get(struct zpdesc *zpdesc) >> +{ >> + folio_get(zpdesc_folio(zpdesc)); >> +} >> + >> +static inline void zpdesc_put(struct zpdesc *zpdesc) >> +{ >> + folio_put(zpdesc_folio(zpdesc)); >> +} >> + >> #endif >> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c >> index a532851025f9..243677a9c6d2 100644 >> --- a/mm/zsmalloc.c >> +++ b/mm/zsmalloc.c >> @@ -433,13 +433,17 @@ static __maybe_unused int is_first_page(struct page *page) >> return PagePrivate(page); >> } >> >> +static int is_first_zpdesc(struct zpdesc *zpdesc) >> +{ >> + return PagePrivate(zpdesc_page(zpdesc)); >> +} >> + > > I feel like we might not even need to use the PG_private flag for > zpages? It seems to me like its just used for sanity checking. Can > zpage->first_page ever not point to the first zpdesc? Yes, the PG_private is only for sanity checking now. But zspage.first_zpdesc are still used widely and must point to the first subpage. I believe we could safely remove this page flag, maybe next patchset? > > For the purpose of introducing the memdesc its fine to continue using > it; just some food for thought. Yes. Thanks a lot! :)