Re: [RFC PATCH] scsi: fix oops in scsi_uninit_cmd()

From: Steffen Maier
Date: Tue Feb 19 2019 - 05:32:37 EST


On 02/19/2019 08:27 AM, Jason Yan wrote:
If we remove the scsi disk when running io with fio, oops occured with
the following condition.

[scsi_eh_0] [fio]
scsi_end_request
->blk_update_request
->end_bio(io returned to userspace)
close
->sd_release
->scsi_disk_put
->scsi_disk_release
->disk->private_data = NULL;

->scsi_mq_uninit_cmd
->scsi_uninit_cmd
->scsi_cmd_to_driver
->drv is NULL, Oops

There is a small window between blk_update_request() and
scsi_mq_uninit_cmd() that scsi disk may have been released. This will
cause a oops like below:

To fix this, get a refcount of scsi_disk in sd_init_command() to ensure
it will not be released before sd_uninit_command().

Signed-off-by: Jason Yan <yanaijie@xxxxxxxxxx>
---
drivers/scsi/sd.c | 46 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 5464d467e23e..6bdb8fbb570f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1249,42 +1249,64 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
{
struct request *rq = cmd->request;
+ struct scsi_disk *sdkp = NULL;

This pre-init with NULL kinda prevents static compile warnings on uninitialized use?

+ blk_status_t ret;

switch (req_op(rq)) {

}
+
+ if (!ret) {
+ sdkp = scsi_disk(rq->rq_disk);
+ get_device(&sdkp->dev);
+ }
+
+ return ret;
}

static void sd_uninit_command(struct scsi_cmnd *SCpnt)
{
struct request *rq = SCpnt->request;
u8 *cmnd;
+ struct scsi_disk *sdkp = NULL;

dito


if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
mempool_free(rq->special_vec.bv_page, sd_page_pool);
@@ -1295,6 +1317,8 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
SCpnt->cmd_len = 0;
mempool_free(cmnd, sd_cdb_pool);
}
+ sdkp = scsi_disk(rq->rq_disk);
+ put_device(&sdkp->dev);
}

/**



--
Mit freundlichen Gruessen / Kind regards
Steffen Maier

Linux on IBM Z Development

https://www.ibm.com/privacy/us/en/
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Matthias Hartmann
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294