scsi: scsi-mq: Always unprepare before requeuing a request
authorBart Van Assche <bart.vanassche@wdc.com>
Wed, 30 Aug 2017 23:58:42 +0000 (16:58 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 1 Sep 2017 03:09:49 +0000 (23:09 -0400)
One of the two scsi-mq functions that requeue a request unprepares a
request before requeueing (scsi_io_completion()) but the other function
not (__scsi_queue_insert()). Make sure that a request is unprepared
before requeuing it.

Fixes: commit d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Damien Le Moal <damien.lemoal@wdc.com>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_lib.c

index 6085377643ae392e934a1034a20bab6cc90bcc7e..9cf6a80fe29754fc93d96d41edb090db2fdd67f4 100644 (file)
@@ -44,6 +44,8 @@ static struct kmem_cache *scsi_sense_cache;
 static struct kmem_cache *scsi_sense_isadma_cache;
 static DEFINE_MUTEX(scsi_sense_cache_mutex);
 
+static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd);
+
 static inline struct kmem_cache *
 scsi_select_sense_cache(bool unchecked_isa_dma)
 {
@@ -140,6 +142,12 @@ static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
 {
        struct scsi_device *sdev = cmd->device;
 
+       if (cmd->request->rq_flags & RQF_DONTPREP) {
+               cmd->request->rq_flags &= ~RQF_DONTPREP;
+               scsi_mq_uninit_cmd(cmd);
+       } else {
+               WARN_ON_ONCE(true);
+       }
        blk_mq_requeue_request(cmd->request, true);
        put_device(&sdev->sdev_gendev);
 }
@@ -982,8 +990,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                 * A new command will be prepared and issued.
                 */
                if (q->mq_ops) {
-                       cmd->request->rq_flags &= ~RQF_DONTPREP;
-                       scsi_mq_uninit_cmd(cmd);
                        scsi_mq_requeue_cmd(cmd);
                } else {
                        scsi_release_buffers(cmd);