All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yosry Ahmed <yosry.ahmed@linux.dev>
To: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Hillf Danton <hdanton@sina.com>, Kairui Song <ryncsn@gmail.com>,
	Minchan Kim <minchan@kernel.org>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6 11/17] zsmalloc: make zspage lock preemptible
Date: Thu, 20 Feb 2025 19:19:39 +0000	[thread overview]
Message-ID: <Z7eAS9T3E5n2i6v4@google.com> (raw)
In-Reply-To: <Z7eAEKpZ7VnGsVej@google.com>

On Thu, Feb 20, 2025 at 07:18:40PM +0000, Yosry Ahmed wrote:
> On Fri, Feb 14, 2025 at 01:50:23PM +0900, Sergey Senozhatsky wrote:
> > In order to implement preemptible object mapping we need a zspage lock
> > that satisfies several preconditions:
> > - it should be reader-write type of a lock
> > - it should be possible to hold it from any context, but also being
> >   preemptible if the context allows it
> > - we never sleep while acquiring but can sleep while holding in read
> >   mode
> > 
> > An rwsemaphore doesn't suffice, due to atomicity requirements, rwlock
> > doesn't satisfy due to reader-preemptability requirement.  It's also
> > worth to mention, that per-zspage rwsem is a little too memory heavy
> > (we can easily have double digits megabytes used only on rwsemaphores).
> > 
> > Switch over from rwlock_t to a atomic_t-based implementation of a
> > reader-writer semaphore that satisfies all of the preconditions.
> > 
> > The spin-lock based zspage_lock is suggested by Hillf Danton.
> > 
> > Suggested-by: Hillf Danton <hdanton@sina.com>
> > Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> > ---
> >  mm/zsmalloc.c | 246 +++++++++++++++++++++++++++++++++++++++-----------
> >  1 file changed, 192 insertions(+), 54 deletions(-)
> > 
> > diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> > index 2e338cde0d21..bc679a3e1718 100644
> > --- a/mm/zsmalloc.c
> > +++ b/mm/zsmalloc.c
> > @@ -226,6 +226,9 @@ struct zs_pool {
> >  	/* protect zspage migration/compaction */
> >  	rwlock_t lock;
> >  	atomic_t compaction_in_progress;
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > +	struct lock_class_key lock_class;
> > +#endif
> >  };
> >  
> >  static inline void zpdesc_set_first(struct zpdesc *zpdesc)
> > @@ -257,6 +260,18 @@ static inline void free_zpdesc(struct zpdesc *zpdesc)
> >  	__free_page(page);
> >  }
> >  
> > +#define ZS_PAGE_UNLOCKED	0
> > +#define ZS_PAGE_WRLOCKED	-1
> > +
> > +struct zspage_lock {
> > +	spinlock_t lock;
> > +	int cnt;
> > +
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > +	struct lockdep_map dep_map;
> > +#endif
> > +};
> > +
> >  struct zspage {
> >  	struct {
> >  		unsigned int huge:HUGE_BITS;
> > @@ -269,7 +284,7 @@ struct zspage {
> >  	struct zpdesc *first_zpdesc;
> >  	struct list_head list; /* fullness list */
> >  	struct zs_pool *pool;
> > -	rwlock_t lock;
> > +	struct zspage_lock zsl;
> >  };
> >  
> >  struct mapping_area {
> > @@ -279,6 +294,148 @@ struct mapping_area {
> >  	enum zs_mapmode vm_mm; /* mapping mode */
> >  };
> >  
> > +static void zspage_lock_init(struct zspage *zspage)
> > +{
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > +	lockdep_init_map(&zspage->zsl.dep_map, "zspage->lock",
> > +			 &zspage->pool->lock_class, 0);
> > +#endif
> > +
> > +	spin_lock_init(&zspage->zsl.lock);
> > +	zspage->zsl.cnt = ZS_PAGE_UNLOCKED;
> > +}
> > +
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> 
> Instead of the #ifdef and repeating all the functions, can't we do
> something like:
> 
> #ifdef CONFIG_DEBUG_LOCK_ALLOC
> #define zspage_lock_map(zsl) (&zsl->dep_map)
> #else
> #define zspage_lock_map(zsl) /* empty or NULL */
> #endif
> 
> Then we can just have one version of the functions and use
> zspage_lock_map() instead of zsl->dep_map, right?
> 
> > +static inline void __read_lock(struct zspage *zspage)
> > +{
> > +	struct zspage_lock *zsl = &zspage->zsl;
> > +
> > +	rwsem_acquire_read(&zsl->dep_map, 0, 0, _RET_IP_);
> > +
> > +	spin_lock(&zsl->lock);
> > +	zsl->cnt++;
> 
> Shouldn't we check if the lock is write locked?

Never mind we keep the spinlock held on write locking.


  reply	other threads:[~2025-02-20 19:19 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-14  4:50 [PATCH v6 00/17] zsmalloc/zram: there be preemption Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 01/17] zram: sleepable entry locking Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 02/17] zram: permit preemption with active compression stream Sergey Senozhatsky
2025-02-20 19:10   ` Yosry Ahmed
2025-02-14  4:50 ` [PATCH v6 03/17] zram: remove unused crypto include Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 04/17] zram: remove max_comp_streams device attr Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 05/17] zram: remove two-staged handle allocation Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 06/17] zram: remove writestall zram_stats member Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 07/17] zram: limit max recompress prio to num_active_comps Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 08/17] zram: filter out recomp targets based on priority Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 09/17] zram: rework recompression loop Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 10/17] zsmalloc: rename pool lock Sergey Senozhatsky
2025-02-20 19:12   ` Yosry Ahmed
2025-02-14  4:50 ` [PATCH v6 11/17] zsmalloc: make zspage lock preemptible Sergey Senozhatsky
2025-02-20 19:18   ` Yosry Ahmed
2025-02-20 19:19     ` Yosry Ahmed [this message]
2025-02-21  1:20     ` Sergey Senozhatsky
2025-02-21 21:01       ` [PATCH v7 " Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 12/17] zsmalloc: introduce new object mapping API Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 13/17] zram: switch to new zsmalloc " Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 14/17] zram: permit reclaim in zstd custom allocator Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 15/17] zram: do not leak page on recompress_store error path Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 16/17] zram: do not leak page on writeback_store " Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 17/17] zram: add might_sleep to zcomp API Sergey Senozhatsky
  -- strict thread matches above, loose matches on Subject: below --
2025-02-21  9:37 [PATCH v7 00/17] zsmalloc/zram: there be preemption Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 01/17] zram: sleepable entry locking Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 02/17] zram: permit preemption with active compression stream Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 03/17] zram: remove unused crypto include Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 04/17] zram: remove max_comp_streams device attr Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 05/17] zram: remove two-staged handle allocation Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 06/17] zram: remove writestall zram_stats member Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 07/17] zram: limit max recompress prio to num_active_comps Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 08/17] zram: filter out recomp targets based on priority Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 09/17] zram: rework recompression loop Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 10/17] zsmalloc: rename pool lock Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 11/17] zsmalloc: make zspage lock preemptible Sergey Senozhatsky
2025-02-21 19:48   ` Yosry Ahmed
2025-02-21 19:52   ` Yosry Ahmed
2025-02-21 22:29     ` Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 12/17] zsmalloc: introduce new object mapping API Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 13/17] zram: switch to new zsmalloc " Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 14/17] zram: permit reclaim in zstd custom allocator Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 15/17] zram: do not leak page on recompress_store error path Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 16/17] zram: do not leak page on writeback_store " Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 17/17] zram: add might_sleep to zcomp API Sergey Senozhatsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z7eAS9T3E5n2i6v4@google.com \
    --to=yosry.ahmed@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=hdanton@sina.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=minchan@kernel.org \
    --cc=ryncsn@gmail.com \
    --cc=senozhatsky@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.