* [PATCH v2 1/6] scsi: core: release SG_IO request before user copyback
2026-10-26 8:29 [PATCH v2 0/6] scsi: release completed passthrough requests before user copyback Yingjie Wang
@ 2026-10-26 8:29 ` Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 2/6] scsi: core: release legacy ioctl " Yingjie Wang
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Yingjie Wang @ 2026-10-26 8:29 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Bart Van Assche, Yang Xiuwei,
Jens Axboe, io-uring@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
From: Yingjie Wang <x-professor@outlook.com>
The block-device SG_IO path retains its completed request while copying
sense data and unmapping the user data buffer. Either operation can fault.
If the fault needs I/O from the same queue and completed requests retain
the available tags, the nested I/O cannot make progress.
Fill the kernel-resident output header and save the bounded sense data
before releasing the request. Then perform the user copies and unmap the
original BIO chain, preserving the existing sense-copy error precedence.
The saved mapping owns its BIO references independently of the request.
The fixed request pool was introduced by scsi-mq; the later move of this
ioctl implementation into drivers/scsi did not introduce the dependency.
Fixes: d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
Link: https://lore.kernel.org/r/20261022.scsi-copyback-review.31b8d6a70f4c@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
drivers/scsi/scsi_ioctl.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 122403ec3ab8d..68e84705634c9 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -393,6 +393,8 @@ static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
struct bio *bio)
{
struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
+ u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
+ unsigned int sense_len = 0;
int r, ret = 0;
/*
@@ -412,10 +414,16 @@ static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
hdr->sb_len_wr = 0;
if (scmd->sense_len && hdr->sbp) {
- int len = min((unsigned int) hdr->mx_sb_len, scmd->sense_len);
+ sense_len = min3(hdr->mx_sb_len, scmd->sense_len,
+ sizeof(sense_buffer));
+ memcpy(sense_buffer, scmd->sense_buffer, sense_len);
+ }
+
+ blk_mq_free_request(rq);
- if (!copy_to_user(hdr->sbp, scmd->sense_buffer, len))
- hdr->sb_len_wr = len;
+ if (sense_len) {
+ if (!copy_to_user(hdr->sbp, sense_buffer, sense_len))
+ hdr->sb_len_wr = sense_len;
else
ret = -EFAULT;
}
@@ -488,7 +496,7 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr,
hdr->duration = jiffies_to_msecs(jiffies - start_time);
- ret = scsi_complete_sghdr_rq(rq, hdr, bio);
+ return scsi_complete_sghdr_rq(rq, hdr, bio);
out_put_request:
blk_mq_free_request(rq);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 2/6] scsi: core: release legacy ioctl request before user copyback
2026-10-26 8:29 [PATCH v2 0/6] scsi: release completed passthrough requests before user copyback Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 1/6] scsi: core: release SG_IO request " Yingjie Wang
@ 2026-10-26 8:29 ` Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 3/6] scsi: sr: release CDDA " Yingjie Wang
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Yingjie Wang @ 2026-10-26 8:29 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Bart Van Assche, Yang Xiuwei,
Jens Axboe, io-uring@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
From: Yingjie Wang <x-professor@outlook.com>
SCSI_IOCTL_SEND_COMMAND copies sense or command data to userspace while
the completed request still occupies its queue tag. A fault that needs
the same queue can therefore wait for a resource held by the ioctl.
Save the command status and the compatibility-limited sense data, then
release the request before copying to userspace. The data buffer is a
separate allocation and remains valid until the existing buffer cleanup.
Keep the positive SCSI status and -EFAULT return conventions unchanged.
This complements the SG_IO fix by covering the legacy
SCSI_IOCTL_SEND_COMMAND path.
Fixes: d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
Link: https://lore.kernel.org/r/20261022.scsi-copyback-review.31b8d6a70f4c@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
drivers/scsi/scsi_ioctl.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 68e84705634c9..95e91ae1332c4 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -533,6 +533,8 @@ static int sg_scsi_ioctl(struct request_queue *q, bool open_for_write,
struct scsi_ioctl_command __user *sic)
{
struct request *rq;
+ u8 sense_buffer[16];
+ unsigned int sense_len = 0;
int err;
unsigned int in_len, out_len, bytes, opcode, cmdlen;
struct scsi_cmnd *scmd;
@@ -621,17 +623,21 @@ static int sg_scsi_ioctl(struct request_queue *q, bool open_for_write,
blk_execute_rq(rq, false);
err = scmd->result & 0xff; /* only 8 bit SCSI status */
+ if (err && scmd->sense_len && scmd->sense_buffer) {
+ /* limit sense len for backward compatibility */
+ sense_len = min(scmd->sense_len, sizeof(sense_buffer));
+ memcpy(sense_buffer, scmd->sense_buffer, sense_len);
+ }
+ blk_mq_free_request(rq);
+
if (err) {
- if (scmd->sense_len && scmd->sense_buffer) {
- /* limit sense len for backward compatibility */
- if (copy_to_user(sic->data, scmd->sense_buffer,
- min(scmd->sense_len, 16U)))
- err = -EFAULT;
- }
+ if (sense_len && copy_to_user(sic->data, sense_buffer, sense_len))
+ err = -EFAULT;
} else {
if (copy_to_user(sic->data, buffer, out_len))
err = -EFAULT;
}
+ goto error_free_buffer;
error:
blk_mq_free_request(rq);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 3/6] scsi: sr: release CDDA request before user copyback
2026-10-26 8:29 [PATCH v2 0/6] scsi: release completed passthrough requests before user copyback Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 1/6] scsi: core: release SG_IO request " Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 2/6] scsi: core: release legacy ioctl " Yingjie Wang
@ 2026-10-26 8:29 ` Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 4/6] scsi: bsg: release synchronous " Yingjie Wang
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Yingjie Wang @ 2026-10-26 8:29 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Bart Van Assche, Yang Xiuwei,
Jens Axboe, io-uring@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
From: Yingjie Wang <x-professor@outlook.com>
sr_read_cdda_bpc() retains its completed request while unmapping the user
buffer. For a bounced data-in mapping, unmapping can copy to userspace
and fault. A fault that needs I/O from the same queue cannot progress if
the completed request retains the available tag.
Release the request after consuming its command result and sense data,
before unmapping the original BIO chain saved at submission. No request
or SCSI command field is accessed after the release. The mapping's BIO
references remain owned by blk_rq_unmap_user().
The scsi-mq request pool introduced this tag dependency. The later move
of the CDDA implementation from drivers/cdrom into sr was a relocation.
Fixes: d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
Link: https://lore.kernel.org/r/20261022.scsi-cdda-lifetime.8f31a2c97b42@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
drivers/scsi/sr.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 4f2e8d1be6da8..c64c25e9f4047 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -969,8 +969,11 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
ret = -EIO;
}
+ blk_mq_free_request(rq);
if (blk_rq_unmap_user(bio))
ret = -EFAULT;
+ return ret;
+
out_put_request:
blk_mq_free_request(rq);
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 4/6] scsi: bsg: release synchronous request before user copyback
2026-10-26 8:29 [PATCH v2 0/6] scsi: release completed passthrough requests before user copyback Yingjie Wang
` (2 preceding siblings ...)
2026-10-26 8:29 ` [PATCH v2 3/6] scsi: sr: release CDDA " Yingjie Wang
@ 2026-10-26 8:29 ` Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 5/6] scsi: bsg: clear io_uring sense length on copy failure Yingjie Wang
2026-10-26 8:29 ` [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O Yingjie Wang
5 siblings, 0 replies; 11+ messages in thread
From: Yingjie Wang @ 2026-10-26 8:29 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Bart Van Assche, Yang Xiuwei,
Jens Axboe, io-uring@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
From: Yingjie Wang <x-professor@outlook.com>
The synchronous SCSI BSG ioctl copies sense data and unmaps its user
data buffer while retaining the completed request. Copyback can fault
and need I/O from the same queue, which cannot progress when completed
requests retain the available tags.
Fill the kernel-resident output fields and save the bounded sense data
before releasing the request. Perform both user copies afterward, using
the original BIO chain saved at mapping time. Preserve the copyback
error precedence established by the separate error-propagation fix.
The SG_IO v4 implementation predates scsi-mq. The fixed scsi-mq request
pool introduced this dependency; moving the callback into scsi_bsg.c
did not change its ownership ordering.
Fixes: d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
Link: https://lore.kernel.org/r/20261022.scsi-copyback-review.31b8d6a70f4c@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
drivers/scsi/scsi_bsg.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index e4a65d7a23742..650facb16ed23 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -199,6 +199,8 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
struct scsi_cmnd *scmd;
struct request *rq;
struct bio *bio;
+ u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
+ unsigned int sense_len = 0;
int ret, unmap_ret;
if (hdr->protocol != BSG_PROTOCOL_SCSI ||
@@ -258,24 +260,28 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
hdr->response_len = 0;
if (scmd->sense_len && hdr->response) {
- int len = min_t(unsigned int, hdr->max_response_len,
- scmd->sense_len);
-
- if (copy_to_user(uptr64(hdr->response), scmd->sense_buffer,
- len))
- ret = -EFAULT;
- else
- hdr->response_len = len;
+ sense_len = min3(hdr->max_response_len, scmd->sense_len,
+ sizeof(sense_buffer));
+ memcpy(sense_buffer, scmd->sense_buffer, sense_len);
}
if (rq_data_dir(rq) == READ)
hdr->din_resid = scmd->resid_len;
else
hdr->dout_resid = scmd->resid_len;
+ blk_mq_free_request(rq);
+
+ if (sense_len) {
+ if (copy_to_user(uptr64(hdr->response), sense_buffer, sense_len))
+ ret = -EFAULT;
+ else
+ hdr->response_len = sense_len;
+ }
unmap_ret = blk_rq_unmap_user(bio);
if (!ret)
ret = unmap_ret;
+ return ret;
out_put_request:
blk_mq_free_request(rq);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 5/6] scsi: bsg: clear io_uring sense length on copy failure
2026-10-26 8:29 [PATCH v2 0/6] scsi: release completed passthrough requests before user copyback Yingjie Wang
` (3 preceding siblings ...)
2026-10-26 8:29 ` [PATCH v2 4/6] scsi: bsg: release synchronous " Yingjie Wang
@ 2026-10-26 8:29 ` Yingjie Wang
2026-10-26 9:40 ` Yang Xiuwei
2026-10-26 8:29 ` [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O Yingjie Wang
5 siblings, 1 reply; 11+ messages in thread
From: Yingjie Wang @ 2026-10-26 8:29 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Bart Van Assche, Yang Xiuwei,
Jens Axboe, io-uring@vger.kernel.org,
linux-kernel@vger.kernel.org
From: Yingjie Wang <x-professor@outlook.com>
The SCSI BSG io_uring completion reports sense_len_wr in res2 as the
number of sense bytes written to the response buffer. If copy_to_user()
fails, the callback returns -EFAULT but leaves that field nonzero.
Clear the reported sense length on a failed copy, matching the
synchronous BSG and SG_IO interfaces. This reporting error predates the
request-lifetime changes and can be fixed independently.
Fixes: 7b6d3255e7f8 ("scsi: bsg: add io_uring passthrough handler")
Link: https://lore.kernel.org/r/20261022.scsi-copyback-review.31b8d6a70f4c@outlook.com
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
drivers/scsi/scsi_bsg.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 650facb16ed23..98c9db1cae653 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -52,8 +52,10 @@ static void scsi_bsg_uring_task_cb(struct io_tw_req tw_req, io_tw_token_t tw)
if (sense_len_wr) {
if (copy_to_user(uptr64(pdu->response_addr), scmd->sense_buffer,
- sense_len_wr))
+ sense_len_wr)) {
ret = -EFAULT;
+ sense_len_wr = 0;
+ }
}
res2 = bsg_scsi_res2_build(status_byte(scmd->result), driver_status,
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v2 5/6] scsi: bsg: clear io_uring sense length on copy failure
2026-10-26 8:29 ` [PATCH v2 5/6] scsi: bsg: clear io_uring sense length on copy failure Yingjie Wang
@ 2026-10-26 9:40 ` Yang Xiuwei
0 siblings, 0 replies; 11+ messages in thread
From: Yang Xiuwei @ 2026-10-26 9:40 UTC (permalink / raw)
To: x-professor
Cc: mkp, James.Bottomley, linux-scsi, bvanassche, axboe, io-uring,
linux-kernel
Hi Yingjie,
On Mon, 26 Oct 2026, Yingjie Wang wrote:
> This reporting error predates the request-lifetime changes and can be
> fixed independently.
6/6 drops sense_len_wr and rebuilds res2 with a zero sense length,
so this does not need to be a separate patch.
Thanks,
Yang Xiuwei
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O
2026-10-26 8:29 [PATCH v2 0/6] scsi: release completed passthrough requests before user copyback Yingjie Wang
` (4 preceding siblings ...)
2026-10-26 8:29 ` [PATCH v2 5/6] scsi: bsg: clear io_uring sense length on copy failure Yingjie Wang
@ 2026-10-26 8:29 ` Yingjie Wang
2026-10-26 9:40 ` Yang Xiuwei
2026-10-26 15:56 ` Bart Van Assche
5 siblings, 2 replies; 11+ messages in thread
From: Yingjie Wang @ 2026-10-26 8:29 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Bart Van Assche, Yang Xiuwei,
Jens Axboe, io-uring@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
From: Yingjie Wang <x-professor@outlook.com>
The SCSI BSG end-I/O callback returns RQ_END_IO_NONE and leaves the
completed request for task work to release. The request therefore
retains its tag before task work runs as well as during user copyback.
With deferred task work, completing the device command alone does not
make that request available to other I/O.
Save the status, residual count and bounded sense data in end-I/O, then
return RQ_END_IO_FREE. Task work can unmap the saved BIO, copy the saved
sense data and publish the CQE without accessing the request or scmd.
Allocate sense storage at submission only when a nonempty response
buffer was requested. Charge this user-triggered allocation to memcg.
Do this before acquiring the request, respect nonblocking allocation,
and return -EAGAIN for an allocation failure that can be retried in
blocking context. Free the storage on submission failure or after
task-work copyback. Reuse the snapshot-capacity field for the packed
completion result after the end-I/O snapshot, keeping the PDU within
32 bytes.
Preallocation avoids relying on a non-sleeping allocation in end-I/O
to preserve sense data after a command has already completed.
Fixes: 7b6d3255e7f8 ("scsi: bsg: add io_uring passthrough handler")
Link: https://lore.kernel.org/r/20261022.scsi-copyback-review.31b8d6a70f4c@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
drivers/scsi/scsi_bsg.c | 78 ++++++++++++++++++++++++++---------------
1 file changed, 49 insertions(+), 29 deletions(-)
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 98c9db1cae653..fafa5c2cdac0e 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bsg.h>
#include <linux/io_uring/cmd.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi_cmnd.h>
@@ -16,9 +17,13 @@
*/
struct scsi_bsg_uring_cmd_pdu {
struct bio *bio; /* mapped user buffer, unmap in task work */
- struct request *req; /* block request, freed in task work */
+ u8 *sense_buffer; /* allocated at submission, freed in task work */
u64 response_addr; /* user space response buffer address */
- u32 max_response_len; /* user response buffer size */
+ /* max_response_len is replaced by res2 after the end-I/O snapshot. */
+ union {
+ u32 max_response_len; /* maximum sense snapshot size */
+ u64 res2; /* saved completion result */
+ };
};
static_assert(sizeof(struct scsi_bsg_uring_cmd_pdu) <= sizeof_field(struct io_uring_cmd, pdu));
@@ -28,41 +33,30 @@ static inline struct scsi_bsg_uring_cmd_pdu *scsi_bsg_uring_cmd_pdu(
return io_uring_cmd_to_pdu(ioucmd, struct scsi_bsg_uring_cmd_pdu);
}
-/* Task work: build res2 (layout in uapi/linux/bsg.h) and copy sense to user. */
+/* Task work: unmap the saved BIO and copy sense to userspace. */
static void scsi_bsg_uring_task_cb(struct io_tw_req tw_req, io_tw_token_t tw)
{
struct io_uring_cmd *ioucmd = io_uring_cmd_from_tw(tw_req);
struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
- struct request *rq = pdu->req;
- struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
- u64 res2;
+ u64 res2 = pdu->res2;
int ret = 0;
- u8 driver_status = 0;
- u8 sense_len_wr = 0;
+ u8 sense_len_wr = bsg_scsi_res2_sense_len(res2);
if (pdu->bio)
ret = blk_rq_unmap_user(pdu->bio);
- if (scsi_status_is_check_condition(scmd->result)) {
- driver_status = DRIVER_SENSE;
- if (pdu->response_addr)
- sense_len_wr = min_t(unsigned int, pdu->max_response_len,
- scmd->sense_len);
- }
-
if (sense_len_wr) {
- if (copy_to_user(uptr64(pdu->response_addr), scmd->sense_buffer,
+ if (copy_to_user(uptr64(pdu->response_addr), pdu->sense_buffer,
sense_len_wr)) {
ret = -EFAULT;
- sense_len_wr = 0;
+ res2 = bsg_scsi_res2_build(bsg_scsi_res2_device_status(res2),
+ bsg_scsi_res2_driver_status(res2),
+ bsg_scsi_res2_host_status(res2), 0,
+ bsg_scsi_res2_resid_len(res2));
}
}
- res2 = bsg_scsi_res2_build(status_byte(scmd->result), driver_status,
- host_byte(scmd->result), sense_len_wr,
- scmd->resid_len);
-
- blk_mq_free_request(rq);
+ kfree(pdu->sense_buffer);
io_uring_cmd_done32(ioucmd, ret, res2,
IO_URING_CMD_TASK_WORK_ISSUE_FLAGS);
}
@@ -72,9 +66,24 @@ static enum rq_end_io_ret scsi_bsg_uring_cmd_done(struct request *req,
const struct io_comp_batch *iocb)
{
struct io_uring_cmd *ioucmd = req->end_io_data;
+ struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+ struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+ u8 driver_status = 0;
+ u8 sense_len = 0;
+
+ if (scsi_status_is_check_condition(scmd->result)) {
+ driver_status = DRIVER_SENSE;
+ if (pdu->sense_buffer) {
+ sense_len = min(pdu->max_response_len, scmd->sense_len);
+ memcpy(pdu->sense_buffer, scmd->sense_buffer, sense_len);
+ }
+ }
+ pdu->res2 = bsg_scsi_res2_build(status_byte(scmd->result), driver_status,
+ host_byte(scmd->result), sense_len,
+ scmd->resid_len);
io_uring_cmd_do_in_task_lazy(ioucmd, scsi_bsg_uring_task_cb);
- return RQ_END_IO_NONE;
+ return RQ_END_IO_FREE;
}
static int scsi_bsg_map_user_buffer(struct request *req,
@@ -139,10 +148,23 @@ static int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *iouc
gfp_mask = GFP_NOWAIT;
}
+ pdu->response_addr = READ_ONCE(cmd->response);
+ pdu->max_response_len = min(READ_ONCE(cmd->max_response_len),
+ SCSI_SENSE_BUFFERSIZE);
+ pdu->sense_buffer = NULL;
+ if (pdu->response_addr && pdu->max_response_len) {
+ pdu->sense_buffer = kmalloc(pdu->max_response_len,
+ gfp_mask | __GFP_ACCOUNT);
+ if (!pdu->sense_buffer)
+ return (issue_flags & IO_URING_F_NONBLOCK) ? -EAGAIN : -ENOMEM;
+ }
+
req = scsi_alloc_request(q, dout_xfer_len ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, blk_flags);
- if (IS_ERR(req))
- return PTR_ERR(req);
+ if (IS_ERR(req)) {
+ ret = PTR_ERR(req);
+ goto out_free_sense;
+ }
scmd = blk_mq_rq_to_pdu(req);
if (request_len > sizeof(scmd->cmnd)) {
@@ -162,9 +184,6 @@ static int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *iouc
goto out_free_req;
}
- pdu->response_addr = cmd->response;
- pdu->max_response_len = cmd->max_response_len;
-
if (dout_xfer_len || din_xfer_len) {
bool is_write = dout_xfer_len > 0;
u64 buf_addr = is_write ? dout_xferp : din_xferp;
@@ -185,13 +204,14 @@ static int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *iouc
req->end_io = scsi_bsg_uring_cmd_done;
req->end_io_data = ioucmd;
- pdu->req = req;
blk_execute_rq_nowait(req, false);
return -EIOCBQUEUED;
out_free_req:
blk_mq_free_request(req);
+out_free_sense:
+ kfree(pdu->sense_buffer);
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O
2026-10-26 8:29 ` [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O Yingjie Wang
@ 2026-10-26 9:40 ` Yang Xiuwei
2026-10-27 9:35 ` Yang Xiuwei
2026-10-26 15:56 ` Bart Van Assche
1 sibling, 1 reply; 11+ messages in thread
From: Yang Xiuwei @ 2026-10-26 9:40 UTC (permalink / raw)
To: x-professor
Cc: mkp, James.Bottomley, linux-scsi, bvanassche, axboe, io-uring,
linux-kernel
Hi Yingjie,
On Mon, 26 Oct 2026, Yingjie Wang wrote:
> + pdu->sense_buffer = kmalloc(pdu->max_response_len,
> + gfp_mask | __GFP_ACCOUNT);
Tested in a VM: INQUIRY batch latency went from 30us to 42us with this
allocation.
The long tag hold is IORING_SETUP_DEFER_TASKRUN. Returning -EOPNOTSUPP
for that flag seems like a compromise. I'd like to hear what others
think.
Thanks,
Yang Xiuwei
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O
2026-10-26 9:40 ` Yang Xiuwei
@ 2026-10-27 9:35 ` Yang Xiuwei
0 siblings, 0 replies; 11+ messages in thread
From: Yang Xiuwei @ 2026-10-27 9:35 UTC (permalink / raw)
To: x-professor
Cc: mkp, James.Bottomley, linux-scsi, bvanassche, axboe, io-uring,
linux-kernel
Hi Yingjie,
On Mon, 26 Oct 2026, Yang Xiuwei wrote:
> Tested in a VM: INQUIRY batch latency went from 30us to 42us with this
> allocation.
For reference: scsi_mq_init_request() already allocates sense_buffer
from scsi_sense_cache. A second buffer from that cache, bsg_sense, can
hold the copy.
Thanks,
Yang Xiuwei
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O
2026-10-26 8:29 ` [PATCH v2 6/6] scsi: bsg: release io_uring requests in end-I/O Yingjie Wang
2026-10-26 9:40 ` Yang Xiuwei
@ 2026-10-26 15:56 ` Bart Van Assche
1 sibling, 0 replies; 11+ messages in thread
From: Bart Van Assche @ 2026-10-26 15:56 UTC (permalink / raw)
To: Yingjie Wang, Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi@vger.kernel.org, Yang Xiuwei, Jens Axboe,
io-uring@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
On 10/26/26 1:29 AM, Yingjie Wang wrote:
> + pdu->response_addr = READ_ONCE(cmd->response);
> + pdu->max_response_len = min(READ_ONCE(cmd->max_response_len),
> + SCSI_SENSE_BUFFERSIZE);
> + pdu->sense_buffer = NULL;
> + if (pdu->response_addr && pdu->max_response_len) {
> + pdu->sense_buffer = kmalloc(pdu->max_response_len,
> + gfp_mask | __GFP_ACCOUNT);
> + if (!pdu->sense_buffer)
> + return (issue_flags & IO_URING_F_NONBLOCK) ? -EAGAIN : -ENOMEM;
> + }
No new kmalloc() calls in the I/O path please. These have a measurable
performance impact.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 11+ messages in thread