All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: linux-block@vger.kernel.org
Cc: Chris Mason <mason@kernel.org>, Christoph Hellwig <hch@lst.de>,
	Sagi Grimberg <sagi@grimberg.me>,
	Chaitanya Kulkarni <kch@nvidia.com>, Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 82/98] nvmet: move preempt and abort work off nvmet-wq
Date: Wed, 28 Oct 2026 10:42:25 -0600	[thread overview]
Message-ID: <20261028164415.1262013-83-axboe@kernel.dk> (raw)
In-Reply-To: <20261028164415.1262013-1-axboe@kernel.dk>

From: Chris Mason <mason@kernel.org>

nvmet_pr_do_abort() runs on nvmet-wq, holds pr_sem while it waits for
the preempted controllers' I/O, and releases it at the end. nvmet-wq
also runs nvmet_tcp_release_queue_work(), which cancel_work_sync()s the
io_work of a closed connection, and that io_work may be sleeping on
pr_sem in a reservation command. So a host that keeps a write in flight
on a preempted controller, sends a second preempt and abort, and then
closes enough connections with a reservation command in flight fills
nvmet-wq with release works that wait for pr_sem. When the first abort
finishes, the second one is queued on a full workqueue behind them and
never starts, pr_sem is never released, and the accept work doesn't run
either, so nobody can connect.

Queue the abort work on its own workqueue so it starts regardless. The
release works can still fill nvmet-wq while pr_sem is held, and a
file-backed namespace's flush, DSM and write zeroes need nvmet-wq
themselves, so this is a mitigation.

Fixes: 5a47c2080a73 ("nvmet: support reservation feature")
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 drivers/nvme/target/core.c  | 11 ++++++++++-
 drivers/nvme/target/nvmet.h |  1 +
 drivers/nvme/target/pr.c    |  6 +++++-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 142df0db5208..f96b21257169 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -29,6 +29,7 @@ struct workqueue_struct *nvmet_wq;
 EXPORT_SYMBOL_GPL(nvmet_wq);
 struct workqueue_struct *nvmet_aen_wq;
 EXPORT_SYMBOL_GPL(nvmet_aen_wq);
+struct workqueue_struct *nvmet_pr_wq;
 
 /*
  * This read/write semaphore is used to synchronize access to configuration
@@ -2034,9 +2035,14 @@ static int __init nvmet_init(void)
 	if (!nvmet_aen_wq)
 		goto out_free_nvmet_work_queue;
 
+	nvmet_pr_wq = alloc_workqueue("nvmet-pr-wq",
+				      WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
+	if (!nvmet_pr_wq)
+		goto out_free_nvmet_aen_work_queue;
+
 	error = nvmet_init_debugfs();
 	if (error)
-		goto out_free_nvmet_aen_work_queue;
+		goto out_free_nvmet_pr_work_queue;
 
 	error = nvmet_init_discovery();
 	if (error)
@@ -2052,6 +2058,8 @@ static int __init nvmet_init(void)
 	nvmet_exit_discovery();
 out_exit_debugfs:
 	nvmet_exit_debugfs();
+out_free_nvmet_pr_work_queue:
+	destroy_workqueue(nvmet_pr_wq);
 out_free_nvmet_aen_work_queue:
 	destroy_workqueue(nvmet_aen_wq);
 out_free_nvmet_work_queue:
@@ -2071,6 +2079,7 @@ static void __exit nvmet_exit(void)
 	nvmet_exit_discovery();
 	nvmet_exit_debugfs();
 	ida_destroy(&cntlid_ida);
+	destroy_workqueue(nvmet_pr_wq);
 	destroy_workqueue(nvmet_aen_wq);
 	destroy_workqueue(nvmet_wq);
 	destroy_workqueue(buffered_io_wq);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 563b966b8f75..9e8fbb2d1fc1 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -532,6 +532,7 @@ extern struct workqueue_struct *buffered_io_wq;
 extern struct workqueue_struct *zbd_wq;
 extern struct workqueue_struct *nvmet_wq;
 extern struct workqueue_struct *nvmet_aen_wq;
+extern struct workqueue_struct *nvmet_pr_wq;
 
 static inline void nvmet_set_result(struct nvmet_req *req, u32 result)
 {
diff --git a/drivers/nvme/target/pr.c b/drivers/nvme/target/pr.c
index 1c0d6cac1a6b..1a03f74c2e14 100644
--- a/drivers/nvme/target/pr.c
+++ b/drivers/nvme/target/pr.c
@@ -756,7 +756,11 @@ static void nvmet_execute_pr_acquire(struct nvmet_req *req)
 	if (!status && acquire_act == NVME_PR_ACQUIRE_ACT_PREEMPT_AND_ABORT) {
 		kfree(d);
 		INIT_WORK(&req->r.abort_work, nvmet_pr_do_abort);
-		queue_work(nvmet_wq, &req->r.abort_work);
+		/*
+		 * Not nvmet_wq: works on it can wait for pr_sem, which this
+		 * work releases.
+		 */
+		queue_work(nvmet_pr_wq, &req->r.abort_work);
 		return;
 	}
 
-- 
2.56.0


  parent reply	other threads:[~2026-10-28 16:46 UTC|newest]

Thread overview: 193+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 16:41 [PATCHSET 0/98] Various block related fixes Jens Axboe
2026-10-28 16:41 ` [PATCH 01/98] blk-cgroup: keep the old blkg while reassociating a bio Jens Axboe
2026-10-28 19:52   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 02/98] blk-iocost: free struct ioc after a grace period Jens Axboe
2026-10-28 20:00   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 03/98] blk-throttle: don't truncate the cgroup v1 iops limits Jens Axboe
2026-10-28 20:00   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 04/98] block: fix use-after-free of the disk in sync_bdevs() Jens Axboe
2026-10-29 12:31   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 05/98] block: don't lose the status of a failed flush request Jens Axboe
2026-10-29 12:32   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 06/98] blk-mq: don't batch allocate tags from an inactive hctx Jens Axboe
2026-10-29 12:35   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 07/98] block: keep zone write plugs with plugged BIOs alive Jens Axboe
2026-10-29 12:44   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 08/98] block: keep the zone write plug of a failed write Jens Axboe
2026-10-29 12:47   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 09/98] blk-mq: end the request if getting a keyslot fails Jens Axboe
2026-10-29 12:51   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 10/98] block: don't unplug a zone under a failed write Jens Axboe
2026-10-28 16:41 ` [PATCH 11/98] block: check dma alignment of bvec iters in async dio Jens Axboe
2026-10-29 12:53   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 12/98] drbd: stop the start_resync timer of a dying device Jens Axboe
2026-10-28 16:41 ` [PATCH 13/98] blk-cgroup: fix root io.stat byte counts on 32-bit Jens Axboe
2026-10-28 19:52   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 14/98] drbd: take req_lock to skip the initial sync as peer Jens Axboe
2026-10-28 16:41 ` [PATCH 15/98] zloop: refuse zone files without read/write_iter Jens Axboe
2026-10-29  7:09   ` Johannes Thumshirn
2026-10-29 12:55   ` Christoph Hellwig
2026-10-29 13:11     ` Jens Axboe
2026-10-28 16:41 ` [PATCH 16/98] block/rnbd-srv: don't free the device on a sysfs error Jens Axboe
2026-10-28 16:41 ` [PATCH 17/98] block/rnbd-srv: drop the sess_dev kobject unlocked Jens Axboe
2026-10-28 16:41 ` [PATCH 18/98] aoe: don't free a device with its work queued Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-29 13:03     ` Jens Axboe
2026-10-28 16:41 ` [PATCH 19/98] blk-cgroup: don't free a blkg with its punt " Jens Axboe
2026-10-28 19:52   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 20/98] mtip32xx: don't mark the disk dead in the irq handler Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-29 12:56   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 21/98] mtip32xx: abort timed out commands of a removed device Jens Axboe
2026-10-28 16:41 ` [PATCH 22/98] mtip32xx: abort commands in flight on surprise removal Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:41 ` [PATCH 23/98] blk-iolatency: flush enable_work after going offline Jens Axboe
2026-10-28 19:52   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 24/98] zram: accept lz4 dictionaries of more than 64 KiB Jens Axboe
2026-10-29  1:20   ` Sergey Senozhatsky
2026-10-29  1:54     ` Jens Axboe
2026-10-29  1:55       ` Sergey Senozhatsky
2026-10-29  2:03         ` Jens Axboe
2026-10-28 16:41 ` [PATCH 25/98] blk-throttle: pass the I/O counts of a dead group on Jens Axboe
2026-10-28 20:00   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 26/98] blk-throttle: make blkio.reset_stats reset I/O counts Jens Axboe
2026-10-28 19:52   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 27/98] blk-mq: don't trust the cookie in blk_mq_poll() Jens Axboe
2026-10-29 12:57   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 28/98] blk-iocost: check again that the disk is alive Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:41 ` [PATCH 29/98] blk-mq: keep sharing tags fairly after a queue update Jens Axboe
2026-10-29 12:57   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 30/98] blk-mq: don't bring back flags of a completed request Jens Axboe
2026-10-29 12:58   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 31/98] blk-mq: don't forget a timer the driver has restarted Jens Axboe
2026-10-29 12:59   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 32/98] blk-mq-dma: initialize the dma state for P2P, too Jens Axboe
2026-10-29 13:03   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 33/98] blk-mq-dma: map the metadata a passthrough request has Jens Axboe
2026-10-29 13:07   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 34/98] block: don't enter reclaim under rq_qos_mutex Jens Axboe
2026-10-28 20:00   ` Tejun Heo
2026-10-28 16:41 ` [PATCH 35/98] blktrace: remove the debugfs files before the channel Jens Axboe
2026-10-28 16:41 ` [PATCH 36/98] blk-mq: quiesce a queue that joins a quiesced tag set Jens Axboe
2026-10-29 13:08   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 37/98] blk-mq: exit the hctxs of a queue under tag_list_lock Jens Axboe
2026-10-29 13:10   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 38/98] blk-mq: set up " Jens Axboe
2026-10-29 13:11   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 39/98] rnbd-srv: fix use-after-free on two CLOSE messages Jens Axboe
2026-10-28 16:41 ` [PATCH 40/98] rnbd-srv: publish the sess_dev at the end of OPEN Jens Axboe
2026-10-28 16:41 ` [PATCH 41/98] zram: check a bio's range against the device size Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:41 ` [PATCH 42/98] block: partitions/mac: compute the sectors in 64 bits Jens Axboe
2026-10-29 13:11   ` Christoph Hellwig
2026-10-29 13:14     ` Jens Axboe
2026-10-28 16:41 ` [PATCH 43/98] blk-mq: free the bitmaps of tags in the SRCU callback Jens Axboe
2026-10-29  7:24   ` Hannes Reinecke
2026-10-29 13:12   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 44/98] block: apply the segment size to the integrity buffer Jens Axboe
2026-10-29 13:13   ` Christoph Hellwig
2026-10-28 16:41 ` [PATCH 45/98] nvmet: don't truncate the length of big discards Jens Axboe
2026-10-29  7:25   ` Hannes Reinecke
2026-10-28 16:41 ` [PATCH 46/98] nvme-loop: delete the controller if a reset fails Jens Axboe
2026-10-28 16:41 ` [PATCH 47/98] nvme: refuse metadata sizes above 255 bytes Jens Axboe
2026-10-28 17:40   ` Keith Busch
2026-10-28 16:41 ` [PATCH 48/98] nvmet-tcp: rewind the iterator after non-data records Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-29  8:58     ` Hannes Reinecke
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:41 ` [PATCH 49/98] nvmet-tcp: ask for the TLS record type on every receive Jens Axboe
2026-10-29  7:38   ` Hannes Reinecke
2026-10-28 16:41 ` [PATCH 50/98] nvme-tcp: wait for an in-flight TLS handshake callback Jens Axboe
2026-10-29  7:40   ` Hannes Reinecke
2026-10-28 16:41 ` [PATCH 51/98] nvmet-tcp: look again after a short read with TLS Jens Axboe
2026-10-28 16:41 ` [PATCH 52/98] nvme-tcp: keep the socket while the queue is polled Jens Axboe
2026-10-28 16:41 ` [PATCH 53/98] nvme-tcp: don't get stuck on a TLS control record Jens Axboe
2026-10-29  7:44   ` Hannes Reinecke
2026-10-28 16:41 ` [PATCH 54/98] nvme-tcp: start error recovery after a TLS KeyUpdate Jens Axboe
2026-10-29  7:49   ` Hannes Reinecke
2026-10-28 16:41 ` [PATCH 55/98] nvme-tcp: don't act on PDUs for a command being sent Jens Axboe
2026-10-28 16:41 ` [PATCH 56/98] nvme-tcp: don't queue the AER while it is " Jens Axboe
2026-10-28 16:42 ` [PATCH 57/98] nvme-tcp: don't send SIGPIPE to whoever submits I/O Jens Axboe
2026-10-28 16:42 ` [PATCH 58/98] nvme-fabrics: reconnect if the association is gone Jens Axboe
2026-10-28 16:42 ` [PATCH 59/98] nvmet-auth: serialize the commands of a controller Jens Axboe
2026-10-29  9:33   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 60/98] nvmet-auth: keep the negotiated hash per queue Jens Axboe
2026-10-29  9:43   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 61/98] nvmet-auth: authenticate the I/O queues again Jens Axboe
2026-10-28 16:42 ` [PATCH 62/98] nvmet: don't mix queues with and without TLS Jens Axboe
2026-10-29  9:52   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 63/98] nvmet-auth: refuse a reply without a DH value Jens Axboe
2026-10-29  9:45   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 64/98] nvmet-auth: keep the old keys if the new ones fail Jens Axboe
2026-10-29  9:53   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 65/98] nvmet-auth: take only AUTH_Negotiate for a negotiation Jens Axboe
2026-10-29  9:55   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 66/98] nvmet-auth: free the old data on a new AUTH_Negotiate Jens Axboe
2026-10-29  9:56   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 67/98] nvmet-auth: fix the check of the offered DH groups Jens Axboe
2026-10-29  9:57   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 68/98] nvmet: accept I/O queues on the controller's port only Jens Axboe
2026-10-29  9:58   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 69/98] nvmet: confine fatal errors of unauthenticated queues Jens Axboe
2026-10-29 10:23   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 70/98] nvmet-tcp: don't wait for the host in the accept work Jens Axboe
2026-10-28 16:42 ` [PATCH 71/98] nvmet: check the host NQN against the TLS PSK identity Jens Axboe
2026-10-28 16:42 ` [PATCH 72/98] nvmet: fix NULL dereference of PCI endpoint targets Jens Axboe
2026-10-28 16:42 ` [PATCH 73/98] nvmet-tcp: stop listening when a port is removed Jens Axboe
2026-10-29 10:02   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 74/98] nvme-tcp: keep the page frag cache with the controller Jens Axboe
2026-10-28 16:42 ` [PATCH 75/98] nvmet-tcp: hold the queue while the TLS timer is armed Jens Axboe
2026-10-28 16:42 ` [PATCH 76/98] nvmet: fix NULL dereference in debugfs host_traddr Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:42 ` [PATCH 77/98] nvmet-tcp: let the accept work come to an end Jens Axboe
2026-10-29 10:06   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 78/98] nvmet-tcp: don't read a removed port at Connect time Jens Axboe
2026-10-28 16:42 ` [PATCH 79/98] nvme-tcp: start error recovery when a send fails Jens Axboe
2026-10-29 10:08   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 80/98] nvme-loop: don't BUG() if a scan runs beside a reset Jens Axboe
2026-10-29 10:08   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 81/98] nvmet: fix pc_ref use-after-free in preempt and abort Jens Axboe
2026-10-28 16:42 ` Jens Axboe [this message]
2026-10-28 16:42 ` [PATCH 83/98] nvmet-rdma: treat a failed connect as a disconnect Jens Axboe
2026-10-28 16:42 ` [PATCH 84/98] nvmet-rdma: disconnect only established queues Jens Axboe
2026-10-28 16:42 ` [PATCH 85/98] nvmet-rdma: take a device off the list last Jens Axboe
2026-10-28 16:42 ` [PATCH 86/98] nvmet-rdma: queue the release work under the mutex Jens Axboe
2026-10-28 16:42 ` [PATCH 87/98] nvmet-rdma: disconnect a queue on device removal Jens Axboe
2026-10-28 16:42 ` [PATCH 88/98] nvmet-rdma: flush nvmet-wq on module exit Jens Axboe
2026-10-28 16:42 ` [PATCH 89/98] nvmet-rdma: reject queues larger than max_cqe Jens Axboe
2026-10-28 16:42 ` [PATCH 90/98] nvmet-rdma: disable interrupts under rsp_wr_wait_lock Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:42 ` [PATCH 91/98] nvmet-rdma: don't run the wait list recursively Jens Axboe
2026-10-28 16:42 ` [PATCH 92/98] nvmet-rdma: fix a lost run of the wait list Jens Axboe
2026-10-28 16:42 ` [PATCH 93/98] nvmet-fc: only send read data for successful commands Jens Axboe
2026-10-29 10:11   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 94/98] nvmet: wait only for executing I/O in preempt and abort Jens Axboe
2026-10-28 16:42 ` [PATCH 95/98] nvmet-rdma: fix double puts after a failed RDMA WRITE Jens Axboe
2026-10-28 16:42 ` [PATCH 96/98] nvmet: take sq->ref in nvmet_sq_fatal_error() Jens Axboe
2026-10-29 10:11   ` Hannes Reinecke
2026-10-28 16:42 ` [PATCH 97/98] nvmet-rdma: hold sq->ref to post a T10-PI Read's SEND Jens Axboe
2026-10-28 19:57   ` Bart Van Assche
2026-10-28 23:49   ` Bart Van Assche
2026-10-28 16:42 ` [PATCH 98/98] nvmet: don't clear sq->ctrl for a Connect with sqsize 0 Jens Axboe
2026-10-29 10:13   ` Hannes Reinecke
2026-10-28 17:11 ` [PATCHSET 0/98] Various block related fixes Keith Busch
2026-10-28 17:13   ` Jens Axboe
2026-10-28 19:12 ` Keith Busch
2026-10-28 19:22 ` Bart Van Assche
2026-10-28 19:29   ` Jens Axboe
2026-10-28 19:47     ` Bart Van Assche
2026-10-28 21:06       ` Jens Axboe
2026-10-28 23:51         ` Bart Van Assche
2026-10-29 13:19           ` Jens Axboe
2026-10-28 19:52   ` Keith Busch
2026-10-28 21:41 ` (subset) " Jens Axboe
2026-10-29 13:22 ` Jens Axboe
2026-10-29 13:25 ` Jens Axboe

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=20261028164415.1262013-83-axboe@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=hch@lst.de \
    --cc=kch@nvidia.com \
    --cc=linux-block@vger.kernel.org \
    --cc=mason@kernel.org \
    --cc=sagi@grimberg.me \
    /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.