All of lore.kernel.org
 help / color / mirror / Atom feed
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
To: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: Pratyush Yadav <pratyush@kernel.org>,
	Michael Walle <mwalle@kernel.org>,
	Takahiro Kuwano <takahiro.kuwano@infineon.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org, Runyu Xiao <runyu.xiao@seu.edu.cn>,
	Jianhao Xu <jianhao.xu@seu.edu.cn>
Subject: [PATCH v4 1/2] mtd: spi-nor: core: Fix mutex leak in spi_nor_rww_start_exclusive()
Date: Wed, 19 Aug 2026 22:03:36 +0800	[thread overview]
Message-ID: <20260819140337.36775-2-runyu.xiao@seu.edu.cn> (raw)
In-Reply-To: <20260819140337.36775-1-runyu.xiao@seu.edu.cn>

The RWW wait helpers must not block while evaluating the condition.
spi_nor_rww_start_exclusive() used mutex_lock() directly and could return
with nor->lock still held.

Switch the four RWW start helpers to conditional scoped mutex guards so
the wait condition never sleeps and nor->lock is released before return.

Fixes: 74df43b3f626 ("mtd: spi-nor: Enhance locking to support reads while writes")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>

Changes in v4:
- Use the original RWW locking commit in Fixes and update the subject.
- Apply the locking fix to all RWW start helpers used as wait conditions.
- Keep commit 03e7bb864d9a ("mtd: spi-nor: use scope-based mutex
  cleanup helpers") as a stable prerequisite because it adds cleanup.h.
---
 drivers/mtd/spi-nor/core.c | 84 ++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index ccf4396cdcd0..d5c6a925862e 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1273,14 +1273,15 @@ static bool spi_nor_rww_start_io(struct spi_nor *nor)
 {
 	struct spi_nor_rww *rww = &nor->rww;
 
-	guard(mutex)(&nor->lock);
-
-	if (rww->ongoing_io)
-		return false;
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io)
+			return false;
 
-	rww->ongoing_io = true;
+		rww->ongoing_io = true;
+		return true;
+	}
 
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_io(struct spi_nor *nor)
@@ -1310,16 +1311,17 @@ static bool spi_nor_rww_start_exclusive(struct spi_nor *nor)
 {
 	struct spi_nor_rww *rww = &nor->rww;
 
-	mutex_lock(&nor->lock);
-
-	if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
-		return false;
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
+			return false;
 
-	rww->ongoing_io = true;
-	rww->ongoing_rd = true;
-	rww->ongoing_pe = true;
+		rww->ongoing_io = true;
+		rww->ongoing_rd = true;
+		rww->ongoing_pe = true;
+		return true;
+	}
 
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_exclusive(struct spi_nor *nor)
@@ -1369,23 +1371,25 @@ static bool spi_nor_rww_start_pe(struct spi_nor *nor, loff_t start, size_t len)
 	u8 first, last;
 	int bank;
 
-	guard(mutex)(&nor->lock);
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
+			return false;
 
-	if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
-		return false;
+		spi_nor_offset_to_banks(nor->params->bank_size, start, len,
+					&first, &last);
+		for (bank = first; bank <= last; bank++) {
+			if (rww->used_banks & BIT(bank))
+				return false;
 
-	spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
-	for (bank = first; bank <= last; bank++) {
-		if (rww->used_banks & BIT(bank))
-			return false;
+			used_banks |= BIT(bank);
+		}
 
-		used_banks |= BIT(bank);
+		rww->used_banks |= used_banks;
+		rww->ongoing_pe = true;
+		return true;
 	}
 
-	rww->used_banks |= used_banks;
-	rww->ongoing_pe = true;
-
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_pe(struct spi_nor *nor, loff_t start, size_t len)
@@ -1440,24 +1444,26 @@ static bool spi_nor_rww_start_rd(struct spi_nor *nor, loff_t start, size_t len)
 	u8 first, last;
 	int bank;
 
-	guard(mutex)(&nor->lock);
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io || rww->ongoing_rd)
+			return false;
 
-	if (rww->ongoing_io || rww->ongoing_rd)
-		return false;
+		spi_nor_offset_to_banks(nor->params->bank_size, start, len,
+					&first, &last);
+		for (bank = first; bank <= last; bank++) {
+			if (rww->used_banks & BIT(bank))
+				return false;
 
-	spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
-	for (bank = first; bank <= last; bank++) {
-		if (rww->used_banks & BIT(bank))
-			return false;
+			used_banks |= BIT(bank);
+		}
 
-		used_banks |= BIT(bank);
+		rww->used_banks |= used_banks;
+		rww->ongoing_io = true;
+		rww->ongoing_rd = true;
+		return true;
 	}
 
-	rww->used_banks |= used_banks;
-	rww->ongoing_io = true;
-	rww->ongoing_rd = true;
-
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_rd(struct spi_nor *nor, loff_t start, size_t len)
-- 
2.34.1

WARNING: multiple messages have this Message-ID (diff)
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
To: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: Pratyush Yadav <pratyush@kernel.org>,
	Michael Walle <mwalle@kernel.org>,
	Takahiro Kuwano <takahiro.kuwano@infineon.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org, Runyu Xiao <runyu.xiao@seu.edu.cn>,
	Jianhao Xu <jianhao.xu@seu.edu.cn>
Subject: [PATCH v4 1/2] mtd: spi-nor: core: Fix mutex leak in spi_nor_rww_start_exclusive()
Date: Wed, 19 Aug 2026 22:03:36 +0800	[thread overview]
Message-ID: <20260819140337.36775-2-runyu.xiao@seu.edu.cn> (raw)
In-Reply-To: <20260819140337.36775-1-runyu.xiao@seu.edu.cn>

The RWW wait helpers must not block while evaluating the condition.
spi_nor_rww_start_exclusive() used mutex_lock() directly and could return
with nor->lock still held.

Switch the four RWW start helpers to conditional scoped mutex guards so
the wait condition never sleeps and nor->lock is released before return.

Fixes: 74df43b3f626 ("mtd: spi-nor: Enhance locking to support reads while writes")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>

Changes in v4:
- Use the original RWW locking commit in Fixes and update the subject.
- Apply the locking fix to all RWW start helpers used as wait conditions.
- Keep commit 03e7bb864d9a ("mtd: spi-nor: use scope-based mutex
  cleanup helpers") as a stable prerequisite because it adds cleanup.h.
---
 drivers/mtd/spi-nor/core.c | 84 ++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index ccf4396cdcd0..d5c6a925862e 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1273,14 +1273,15 @@ static bool spi_nor_rww_start_io(struct spi_nor *nor)
 {
 	struct spi_nor_rww *rww = &nor->rww;
 
-	guard(mutex)(&nor->lock);
-
-	if (rww->ongoing_io)
-		return false;
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io)
+			return false;
 
-	rww->ongoing_io = true;
+		rww->ongoing_io = true;
+		return true;
+	}
 
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_io(struct spi_nor *nor)
@@ -1310,16 +1311,17 @@ static bool spi_nor_rww_start_exclusive(struct spi_nor *nor)
 {
 	struct spi_nor_rww *rww = &nor->rww;
 
-	mutex_lock(&nor->lock);
-
-	if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
-		return false;
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
+			return false;
 
-	rww->ongoing_io = true;
-	rww->ongoing_rd = true;
-	rww->ongoing_pe = true;
+		rww->ongoing_io = true;
+		rww->ongoing_rd = true;
+		rww->ongoing_pe = true;
+		return true;
+	}
 
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_exclusive(struct spi_nor *nor)
@@ -1369,23 +1371,25 @@ static bool spi_nor_rww_start_pe(struct spi_nor *nor, loff_t start, size_t len)
 	u8 first, last;
 	int bank;
 
-	guard(mutex)(&nor->lock);
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
+			return false;
 
-	if (rww->ongoing_io || rww->ongoing_rd || rww->ongoing_pe)
-		return false;
+		spi_nor_offset_to_banks(nor->params->bank_size, start, len,
+					&first, &last);
+		for (bank = first; bank <= last; bank++) {
+			if (rww->used_banks & BIT(bank))
+				return false;
 
-	spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
-	for (bank = first; bank <= last; bank++) {
-		if (rww->used_banks & BIT(bank))
-			return false;
+			used_banks |= BIT(bank);
+		}
 
-		used_banks |= BIT(bank);
+		rww->used_banks |= used_banks;
+		rww->ongoing_pe = true;
+		return true;
 	}
 
-	rww->used_banks |= used_banks;
-	rww->ongoing_pe = true;
-
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_pe(struct spi_nor *nor, loff_t start, size_t len)
@@ -1440,24 +1444,26 @@ static bool spi_nor_rww_start_rd(struct spi_nor *nor, loff_t start, size_t len)
 	u8 first, last;
 	int bank;
 
-	guard(mutex)(&nor->lock);
+	scoped_guard(mutex_try, &nor->lock) {
+		if (rww->ongoing_io || rww->ongoing_rd)
+			return false;
 
-	if (rww->ongoing_io || rww->ongoing_rd)
-		return false;
+		spi_nor_offset_to_banks(nor->params->bank_size, start, len,
+					&first, &last);
+		for (bank = first; bank <= last; bank++) {
+			if (rww->used_banks & BIT(bank))
+				return false;
 
-	spi_nor_offset_to_banks(nor->params->bank_size, start, len, &first, &last);
-	for (bank = first; bank <= last; bank++) {
-		if (rww->used_banks & BIT(bank))
-			return false;
+			used_banks |= BIT(bank);
+		}
 
-		used_banks |= BIT(bank);
+		rww->used_banks |= used_banks;
+		rww->ongoing_io = true;
+		rww->ongoing_rd = true;
+		return true;
 	}
 
-	rww->used_banks |= used_banks;
-	rww->ongoing_io = true;
-	rww->ongoing_rd = true;
-
-	return true;
+	return false;
 }
 
 static void spi_nor_rww_end_rd(struct spi_nor *nor, loff_t start, size_t len)
-- 
2.34.1

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2026-08-19 14:03 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-09  8:42 [PATCH] mtd: spi-nor: scope the exclusive RWW lock Runyu Xiao
2026-08-09  8:42 ` Runyu Xiao
2026-08-10  8:25 ` Michael Walle
2026-08-10  8:25   ` Michael Walle
2026-08-10 12:47   ` Miquel Raynal
2026-08-10 12:47     ` Miquel Raynal
2026-08-11  4:13   ` [PATCH v2] " Runyu Xiao
2026-08-11  4:13     ` Runyu Xiao
2026-08-11  7:51     ` Miquel Raynal
2026-08-11  7:51       ` Miquel Raynal
2026-08-11  8:31     ` [PATCH v3] mtd: spi-nor: use guard() in spi_nor_rww_start_exclusive Runyu Xiao
2026-08-11  8:31       ` Runyu Xiao
2026-08-11  8:41       ` Miquel Raynal
2026-08-11  8:41         ` Miquel Raynal
2026-08-11 10:11       ` Tudor Ambarus
2026-08-11 10:11         ` Tudor Ambarus
2026-08-11 10:42         ` Tudor Ambarus
2026-08-11 10:42           ` Tudor Ambarus
2026-08-11 14:36           ` Miquel Raynal
2026-08-11 14:36             ` Miquel Raynal
2026-08-11 15:38             ` Miquel Raynal
2026-08-11 15:38               ` Miquel Raynal
2026-08-12 10:19               ` Tudor Ambarus
2026-08-12 10:19                 ` Tudor Ambarus
2026-08-19 14:03                 ` [PATCH v4 0/2] mtd: spi-nor: core: Fix RWW wait locking Runyu Xiao
2026-08-19 14:03                   ` Runyu Xiao
2026-08-19 14:03                   ` Runyu Xiao [this message]
2026-08-19 14:03                     ` [PATCH v4 1/2] mtd: spi-nor: core: Fix mutex leak in spi_nor_rww_start_exclusive() Runyu Xiao
2026-08-25 12:29                     ` Miquel Raynal
2026-08-25 12:29                       ` Miquel Raynal
2026-08-27  8:26                       ` [PATCH v5] " Runyu Xiao
2026-08-27  8:33                         ` Miquel Raynal
2026-08-27  8:45                           ` Runyu Xiao
2026-08-19 14:03                   ` [PATCH v4 2/2] mtd: spi-nor: core: Unprepare after interrupted RWW wait Runyu Xiao
2026-08-19 14:03                     ` Runyu Xiao
2026-08-25 12:18                     ` Miquel Raynal
2026-08-25 12:18                       ` Miquel Raynal
2026-08-12  9:49       ` [PATCH v3] mtd: spi-nor: use guard() in spi_nor_rww_start_exclusive Tudor Ambarus
2026-08-12  9:49         ` Tudor Ambarus
2026-08-11  8:50     ` [PATCH v2] mtd: spi-nor: scope the exclusive RWW lock Michael Walle
2026-08-11  8:50       ` Michael Walle
2026-08-11 10:05   ` [PATCH] " Tudor Ambarus
2026-08-11 10:05     ` Tudor Ambarus
2026-08-12  6:14     ` Michael Walle
2026-08-12  6:14       ` Michael Walle
2026-08-12  9:48       ` Tudor Ambarus
2026-08-12  9:48         ` Tudor Ambarus

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=20260819140337.36775-2-runyu.xiao@seu.edu.cn \
    --to=runyu.xiao@seu.edu.cn \
    --cc=jianhao.xu@seu.edu.cn \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=miquel.raynal@bootlin.com \
    --cc=mwalle@kernel.org \
    --cc=pratyush@kernel.org \
    --cc=richard@nod.at \
    --cc=stable@vger.kernel.org \
    --cc=takahiro.kuwano@infineon.com \
    --cc=tudor.ambarus@linaro.org \
    --cc=vigneshr@ti.com \
    /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.