storvsc: ring buffer failures may result in I/O freeze
[cascardo/linux.git] / drivers / scsi / scsi_lib.c
index 9eff8a3..994eb08 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/hardirq.h>
 #include <linux/scatterlist.h>
 #include <linux/blk-mq.h>
+#include <linux/ratelimit.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -47,7 +48,7 @@ struct scsi_host_sg_pool {
        mempool_t       *pool;
 };
 
-#define SP(x) { x, "sgpool-" __stringify(x) }
+#define SP(x) { .size = x, "sgpool-" __stringify(x) }
 #if (SCSI_MAX_SG_SEGMENTS < 32)
 #error SCSI_MAX_SG_SEGMENTS is too small (must be 32 or greater)
 #endif
@@ -831,8 +832,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        struct request *req = cmd->request;
        int error = 0;
        struct scsi_sense_hdr sshdr;
-       int sense_valid = 0;
-       int sense_deferred = 0;
+       bool sense_valid = false;
+       int sense_deferred = 0, level = 0;
        enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY,
              ACTION_DELAYED_RETRY} action;
        unsigned long wait_for = (cmd->allowed + 1) * req->timeout;
@@ -912,7 +913,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d))
                        ;
                else if (!(req->cmd_flags & REQ_QUIET))
-                       scsi_print_sense("", cmd);
+                       scsi_print_sense(cmd);
                result = 0;
                /* BLOCK_PC may have set error */
                error = 0;
@@ -1039,10 +1040,24 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        case ACTION_FAIL:
                /* Give up and fail the remainder of the request */
                if (!(req->cmd_flags & REQ_QUIET)) {
-                       scsi_print_result(cmd);
-                       if (driver_byte(result) & DRIVER_SENSE)
-                               scsi_print_sense("", cmd);
-                       scsi_print_command(cmd);
+                       static DEFINE_RATELIMIT_STATE(_rs,
+                                       DEFAULT_RATELIMIT_INTERVAL,
+                                       DEFAULT_RATELIMIT_BURST);
+
+                       if (unlikely(scsi_logging_level))
+                               level = SCSI_LOG_LEVEL(SCSI_LOG_MLCOMPLETE_SHIFT,
+                                                      SCSI_LOG_MLCOMPLETE_BITS);
+
+                       /*
+                        * if logging is enabled the failure will be printed
+                        * in scsi_log_completion(), so avoid duplicate messages
+                        */
+                       if (!level && __ratelimit(&_rs)) {
+                               scsi_print_result(cmd, NULL, FAILED);
+                               if (driver_byte(result) & DRIVER_SENSE)
+                                       scsi_print_sense(cmd);
+                               scsi_print_command(cmd);
+                       }
                }
                if (!scsi_end_request(req, error, blk_rq_err_bytes(req), 0))
                        return;
@@ -1725,7 +1740,7 @@ static void scsi_request_fn(struct request_queue *q)
                 * we add the dev to the starved list so it eventually gets
                 * a run when a tag is freed.
                 */
-               if (blk_queue_tagged(q) && !blk_rq_tagged(req)) {
+               if (blk_queue_tagged(q) && !(req->cmd_flags & REQ_QUEUED)) {
                        spin_lock_irq(shost->host_lock);
                        if (list_empty(&sdev->starved_entry))
                                list_add_tail(&sdev->starved_entry,
@@ -1739,6 +1754,11 @@ static void scsi_request_fn(struct request_queue *q)
 
                if (!scsi_host_queue_ready(q, shost, sdev))
                        goto host_not_ready;
+       
+               if (sdev->simple_tags)
+                       cmd->flags |= SCMD_TAGGED;
+               else
+                       cmd->flags &= ~SCMD_TAGGED;
 
                /*
                 * Finally, initialize any error handling parameters, and set up
@@ -1893,6 +1913,11 @@ static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req,
                blk_mq_start_request(req);
        }
 
+       if (sdev->simple_tags)
+               cmd->flags |= SCMD_TAGGED;
+       else
+               cmd->flags &= ~SCMD_TAGGED;
+
        scsi_init_cmd_errh(cmd);
        cmd->scsi_done = scsi_mq_done;
 
@@ -2086,7 +2111,7 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
 
        memset(&shost->tag_set, 0, sizeof(shost->tag_set));
        shost->tag_set.ops = &scsi_mq_ops;
-       shost->tag_set.nr_hw_queues = 1;
+       shost->tag_set.nr_hw_queues = shost->nr_hw_queues ? : 1;
        shost->tag_set.queue_depth = shost->can_queue;
        shost->tag_set.cmd_size = cmd_size;
        shost->tag_set.numa_node = NUMA_NO_NODE;