scsi: Improve requeuing behavior

Requests are unprepared and reprepared when being requeued. Avoid that
requeuing resets .jiffies_at_alloc and .retries by initializing these
two member variables from inside scsi_initialize_rq() and by preserving
both member variables when preparing a request. This patch affects the
requeuing behavior of both the legacy scsi and the scsi-mq code paths.

Reported-by: Brian King <brking@linux.vnet.ibm.com>
References: https://lkml.org/lkml/2017/8/18/923 ("Re: [BUG][bisected 270065e] linux-next fails to boot on powerpc")
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Brian King <brking@linux.vnet.ibm.com>
Cc: Hannes Reinecke <hare@suse.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>

authored by

Bart Van Assche and committed by
Martin K. Petersen
832889f5 64104f70

+13 -2
+13 -2
drivers/scsi/scsi_lib.c
··· 1112 EXPORT_SYMBOL(scsi_init_io); 1113 1114 /** 1115 - * scsi_initialize_rq - initialize struct scsi_cmnd.req 1116 * @rq: Request associated with the SCSI command to be initialized. 1117 * 1118 * Called from inside blk_get_request() for pass-through requests and from 1119 * inside scsi_init_command() for filesystem requests. ··· 1127 struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); 1128 1129 scsi_req_init(&cmd->req); 1130 } 1131 EXPORT_SYMBOL(scsi_initialize_rq); 1132 ··· 1168 void *prot = cmd->prot_sdb; 1169 struct request *rq = blk_mq_rq_from_pdu(cmd); 1170 unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; 1171 1172 if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) { 1173 flags |= SCMD_INITIALIZED; 1174 scsi_initialize_rq(rq); 1175 } 1176 1177 /* zero out the cmd, except for the embedded scsi_request */ 1178 memset((char *)cmd + sizeof(cmd->req), 0, 1179 sizeof(*cmd) - sizeof(cmd->req) + dev->host->hostt->cmd_size); ··· 1187 cmd->prot_sdb = prot; 1188 cmd->flags = flags; 1189 INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); 1190 - cmd->jiffies_at_alloc = jiffies; 1191 1192 scsi_add_cmd_to_list(cmd); 1193 }
··· 1112 EXPORT_SYMBOL(scsi_init_io); 1113 1114 /** 1115 + * scsi_initialize_rq - initialize struct scsi_cmnd partially 1116 * @rq: Request associated with the SCSI command to be initialized. 1117 + * 1118 + * This function initializes the members of struct scsi_cmnd that must be 1119 + * initialized before request processing starts and that won't be 1120 + * reinitialized if a SCSI command is requeued. 1121 * 1122 * Called from inside blk_get_request() for pass-through requests and from 1123 * inside scsi_init_command() for filesystem requests. ··· 1123 struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); 1124 1125 scsi_req_init(&cmd->req); 1126 + cmd->jiffies_at_alloc = jiffies; 1127 + cmd->retries = 0; 1128 } 1129 EXPORT_SYMBOL(scsi_initialize_rq); 1130 ··· 1162 void *prot = cmd->prot_sdb; 1163 struct request *rq = blk_mq_rq_from_pdu(cmd); 1164 unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; 1165 + unsigned long jiffies_at_alloc; 1166 + int retries; 1167 1168 if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) { 1169 flags |= SCMD_INITIALIZED; 1170 scsi_initialize_rq(rq); 1171 } 1172 1173 + jiffies_at_alloc = cmd->jiffies_at_alloc; 1174 + retries = cmd->retries; 1175 /* zero out the cmd, except for the embedded scsi_request */ 1176 memset((char *)cmd + sizeof(cmd->req), 0, 1177 sizeof(*cmd) - sizeof(cmd->req) + dev->host->hostt->cmd_size); ··· 1177 cmd->prot_sdb = prot; 1178 cmd->flags = flags; 1179 INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); 1180 + cmd->jiffies_at_alloc = jiffies_at_alloc; 1181 + cmd->retries = retries; 1182 1183 scsi_add_cmd_to_list(cmd); 1184 }