diff options
author | Bart Van Assche <bart.vanassche@wdc.com> | 2017-10-20 14:46:45 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-10-23 04:19:45 -0400 |
commit | 8fe8ffb12c81b36877984274db184953c337db73 (patch) | |
tree | 3437ca4c6c036056141802352ae4a2abbc82f50e | |
parent | 587c3c9f286cee5c9cac38d28c8ae1875f4ec85b (diff) |
scsi: Suppress a kernel warning in case the prep function returns BLKPREP_DEFER
The legacy block layer handles requests as follows:
- If the prep function returns BLKPREP_OK, let blk_peek_request()
return the pointer to that request.
- If the prep function returns BLKPREP_DEFER, keep the RQF_STARTED
flag and retry calling the prep function later.
- If the prep function returns BLKPREP_KILL or BLKPREP_INVALID, end
the request.
In none of these cases it is correct to clear the SCMD_INITIALIZED
flag from inside scsi_prep_fn(). Since scsi_prep_fn() already
guarantees that scsi_init_command() will be called once even if
scsi_prep_fn() is called multiple times, remove the code that clears
SCMD_INITIALIZED from scsi_prep_fn().
The scsi-mq code handles requests as follows:
- If scsi_mq_prep_fn() returns BLKPREP_OK, set the RQF_DONTPREP flag
and submit the request to the SCSI LLD.
- If scsi_mq_prep_fn() returns BLKPREP_DEFER, call
blk_mq_delay_run_hw_queue() and return BLK_STS_RESOURCE.
- If the prep function returns BLKPREP_KILL or BLKPREP_INVALID, call
scsi_mq_uninit_cmd() and let the blk-mq core end the request.
In none of these cases scsi_mq_prep_fn() should clear the
SCMD_INITIALIZED flag. Hence remove the code from scsi_mq_prep_fn()
function that clears that flag.
This patch avoids that the following warning is triggered when using
the legacy block layer:
------------[ cut here ]------------
WARNING: CPU: 1 PID: 4198 at drivers/scsi/scsi_lib.c:654 scsi_end_request+0x1de/0x220
CPU: 1 PID: 4198 Comm: mkfs.f2fs Not tainted 4.14.0-rc5+ #1
task: ffff91c147a4b800 task.stack: ffffb282c37b8000
RIP: 0010:scsi_end_request+0x1de/0x220
Call Trace:
<IRQ>
scsi_io_completion+0x204/0x5e0
scsi_finish_command+0xce/0xe0
scsi_softirq_done+0x126/0x130
blk_done_softirq+0x6e/0x80
__do_softirq+0xcf/0x2a8
irq_exit+0xab/0xb0
do_IRQ+0x7b/0xc0
common_interrupt+0x90/0x90
</IRQ>
RIP: 0010:_raw_spin_unlock_irqrestore+0x9/0x10
__test_set_page_writeback+0xc7/0x2c0
__block_write_full_page+0x158/0x3b0
block_write_full_page+0xc4/0xd0
blkdev_writepage+0x13/0x20
__writepage+0x12/0x40
write_cache_pages+0x204/0x500
generic_writepages+0x48/0x70
blkdev_writepages+0x9/0x10
do_writepages+0x34/0xc0
__filemap_fdatawrite_range+0x6c/0x90
file_write_and_wait_range+0x31/0x90
blkdev_fsync+0x16/0x40
vfs_fsync_range+0x44/0xa0
do_fsync+0x38/0x60
SyS_fsync+0xb/0x10
entry_SYSCALL_64_fastpath+0x13/0x94
---[ end trace 86e8ef85a4a6c1d1 ]---
Fixes: commit 64104f703212 ("scsi: Call scsi_initialize_rq() for filesystem requests")
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Damien Le Moal <damien.lemoal@wdc.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 8 |
1 files changed, 1 insertions, 7 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9cf6a80fe297..ad3ea24f0885 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1379,8 +1379,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1379 | 1379 | ||
1380 | ret = scsi_setup_cmnd(sdev, req); | 1380 | ret = scsi_setup_cmnd(sdev, req); |
1381 | out: | 1381 | out: |
1382 | if (ret != BLKPREP_OK) | ||
1383 | cmd->flags &= ~SCMD_INITIALIZED; | ||
1384 | return scsi_prep_return(q, req, ret); | 1382 | return scsi_prep_return(q, req, ret); |
1385 | } | 1383 | } |
1386 | 1384 | ||
@@ -1900,7 +1898,6 @@ static int scsi_mq_prep_fn(struct request *req) | |||
1900 | struct scsi_device *sdev = req->q->queuedata; | 1898 | struct scsi_device *sdev = req->q->queuedata; |
1901 | struct Scsi_Host *shost = sdev->host; | 1899 | struct Scsi_Host *shost = sdev->host; |
1902 | struct scatterlist *sg; | 1900 | struct scatterlist *sg; |
1903 | int ret; | ||
1904 | 1901 | ||
1905 | scsi_init_command(sdev, cmd); | 1902 | scsi_init_command(sdev, cmd); |
1906 | 1903 | ||
@@ -1934,10 +1931,7 @@ static int scsi_mq_prep_fn(struct request *req) | |||
1934 | 1931 | ||
1935 | blk_mq_start_request(req); | 1932 | blk_mq_start_request(req); |
1936 | 1933 | ||
1937 | ret = scsi_setup_cmnd(sdev, req); | 1934 | return scsi_setup_cmnd(sdev, req); |
1938 | if (ret != BLK_STS_OK) | ||
1939 | cmd->flags &= ~SCMD_INITIALIZED; | ||
1940 | return ret; | ||
1941 | } | 1935 | } |
1942 | 1936 | ||
1943 | static void scsi_mq_done(struct scsi_cmnd *cmd) | 1937 | static void scsi_mq_done(struct scsi_cmnd *cmd) |