mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Yosry Ahmed <yosry.ahmed@linux.dev>,
	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 v8 01/17] zram: sleepable entry locking
Date: Mon, 24 Feb 2025 09:19:56 +0100	[thread overview]
Message-ID: <20250224081956.knanS8L_@linutronix.de> (raw)
In-Reply-To: <20250221222958.2225035-2-senozhatsky@chromium.org>

On 2025-02-22 07:25:32 [+0900], Sergey Senozhatsky wrote:
…
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 9f5020b077c5..37c5651305c2 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -58,19 +58,62 @@ static void zram_free_page(struct zram *zram, size_t index);
>  static int zram_read_from_zspool(struct zram *zram, struct page *page,
>  				 u32 index);
>  
> -static int zram_slot_trylock(struct zram *zram, u32 index)
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +#define slot_dep_map(zram, index) (&(zram)->table[(index)].dep_map)
> +#define zram_lock_class(zram) (&(zram)->lock_class)
> +#else
> +#define slot_dep_map(zram, index) NULL
> +#define zram_lock_class(zram) NULL
> +#endif

That CONFIG_DEBUG_LOCK_ALLOC here is not needed because dep_map as well
as lock_class goes away in !CONFIG_DEBUG_LOCK_ALLOC case.

> +static void zram_slot_lock_init(struct zram *zram, u32 index)
>  {
> -	return spin_trylock(&zram->table[index].lock);
> +	lockdep_init_map(slot_dep_map(zram, index),
> +			 "zram->table[index].lock",
> +			 zram_lock_class(zram), 0);
> +}
Why do need zram_lock_class and slot_dep_map? As far as I can tell, you
init both in the same place and you acquire both in the same place.
Therefore it looks like you tell lockdep that you acquire two locks
while it would be enough to do it with one.

> +/*
> + * entry locking rules:
> + *
> + * 1) Lock is exclusive
> + *
> + * 2) lock() function can sleep waiting for the lock
> + *
> + * 3) Lock owner can sleep
> + *
> + * 4) Use TRY lock variant when in atomic context
> + *    - must check return value and handle locking failers
> + */
> +static __must_check bool zram_slot_trylock(struct zram *zram, u32 index)
> +{
> +	unsigned long *lock = &zram->table[index].flags;
> +
> +	if (!test_and_set_bit_lock(ZRAM_ENTRY_LOCK, lock)) {
> +		mutex_acquire(slot_dep_map(zram, index), 0, 1, _RET_IP_);
> +		lock_acquired(slot_dep_map(zram, index), _RET_IP_);
> +		return true;
> +	}
> +
> +	lock_contended(slot_dep_map(zram, index), _RET_IP_);
> +	return false;
>  }
>  
>  static void zram_slot_lock(struct zram *zram, u32 index)
>  {
> -	spin_lock(&zram->table[index].lock);
> +	unsigned long *lock = &zram->table[index].flags;
> +
> +	mutex_acquire(slot_dep_map(zram, index), 0, 0, _RET_IP_);
> +	wait_on_bit_lock(lock, ZRAM_ENTRY_LOCK, TASK_UNINTERRUPTIBLE);
> +	lock_acquired(slot_dep_map(zram, index), _RET_IP_);

This looks odd. The first mutex_acquire() can be invoked twice by two
threads, right? The first thread gets both (mutex_acquire() and
lock_acquired()) while, the second gets mutex_acquire() and blocks on
wait_on_bit_lock()).

>  }
>  
>  static void zram_slot_unlock(struct zram *zram, u32 index)
>  {
> -	spin_unlock(&zram->table[index].lock);
> +	unsigned long *lock = &zram->table[index].flags;
> +
> +	mutex_release(slot_dep_map(zram, index), _RET_IP_);
> +	clear_and_wake_up_bit(ZRAM_ENTRY_LOCK, lock);
>  }
>  
>  static inline bool init_done(struct zram *zram)
…
> diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
> index db78d7c01b9a..794c9234e627 100644
> --- a/drivers/block/zram/zram_drv.h
> +++ b/drivers/block/zram/zram_drv.h
> @@ -58,13 +58,18 @@ enum zram_pageflags {
>  	__NR_ZRAM_PAGEFLAGS,
>  };
>  
> -/*-- Data structures */
> -
> -/* Allocated for each disk page */
> +/*
> + * Allocated for each disk page.  We use bit-lock (ZRAM_ENTRY_LOCK bit
> + * of flags) to save memory.  There can be plenty of entries and standard
> + * locking primitives (e.g. mutex) will significantly increase sizeof()
> + * of each entry and hence of the meta table.
> + */
>  struct zram_table_entry {
>  	unsigned long handle;
> -	unsigned int flags;
> -	spinlock_t lock;
> +	unsigned long flags;
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	struct lockdep_map dep_map;
> +#endif
>  #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
>  	ktime_t ac_time;
>  #endif
> @@ -137,5 +142,8 @@ struct zram {
>  	struct dentry *debugfs_dir;
>  #endif
>  	atomic_t pp_in_progress;
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	struct lock_class_key lock_class;
> +#endif
As mentioned earlier, no need for CONFIG_DEBUG_LOCK_ALLOC.

>  };
>  #endif
> -- 
> 2.48.1.601.g30ceb7b040-goog
> 

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

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-21 22:25 [PATCH v8 00/17] zsmalloc/zram: there be preemption Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 01/17] zram: sleepable entry locking Sergey Senozhatsky
2025-02-24  8:19   ` Sebastian Andrzej Siewior [this message]
2025-02-25  4:51     ` Sergey Senozhatsky
2025-02-27 12:05       ` Sebastian Andrzej Siewior
2025-02-27 12:42         ` Sergey Senozhatsky
2025-02-27 13:04           ` Sergey Senozhatsky
2025-02-27 13:12             ` Sebastian Andrzej Siewior
2025-02-27 13:20               ` Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 02/17] zram: permit preemption with active compression stream Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 03/17] zram: remove unused crypto include Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 04/17] zram: remove max_comp_streams device attr Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 05/17] zram: remove second stage of handle allocation Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 06/17] zram: remove writestall zram_stats member Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 07/17] zram: limit max recompress prio to num_active_comps Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 08/17] zram: filter out recomp targets based on priority Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 09/17] zram: rework recompression loop Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 10/17] zsmalloc: rename pool lock Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 11/17] zsmalloc: make zspage lock preemptible Sergey Senozhatsky
2025-02-24  8:59   ` Sebastian Andrzej Siewior
2025-02-25  4:28     ` Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 12/17] zsmalloc: introduce new object mapping API Sergey Senozhatsky
2025-02-24  9:01   ` Sebastian Andrzej Siewior
2025-02-25  4:29     ` Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 13/17] zram: switch to new zsmalloc " Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 14/17] zram: permit reclaim in zstd custom allocator Sergey Senozhatsky
2025-02-24  9:10   ` Sebastian Andrzej Siewior
2025-02-25  4:42     ` Sergey Senozhatsky
2025-02-26  3:01       ` Sergey Senozhatsky
2025-02-27 13:19       ` Sebastian Andrzej Siewior
2025-02-21 22:25 ` [PATCH v8 15/17] zram: do not leak page on recompress_store error path Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 16/17] zram: do not leak page on writeback_store " Sergey Senozhatsky
2025-02-21 22:25 ` [PATCH v8 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=20250224081956.knanS8L_@linutronix.de \
    --to=bigeasy@linutronix.de \
    --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 \
    --cc=yosry.ahmed@linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®