scsi: ratelimit I/O error messages
authorHannes Reinecke <hare@suse.de>
Fri, 24 Oct 2014 12:27:07 +0000 (14:27 +0200)
committerChristoph Hellwig <hch@lst.de>
Wed, 12 Nov 2014 10:16:08 +0000 (11:16 +0100)
There can be quite a lot of I/O error messages, even on smaller
machines. So we need to ratelimit them to not overwhelm logging.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Tested-by: Robert Elliott <elliott@hp.com>
Reviewed-by: Robert Elliott <elliott@hp.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/scsi_lib.c

index 26a57faf885b33f87693bcc9f84e6bed42ce058f..fc0a8a0c0a34cd584d72996196d618ceceed34cd 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>
@@ -1038,18 +1039,25 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        switch (action) {
        case ACTION_FAIL:
                /* Give up and fail the remainder of the request */
-               if (unlikely(scsi_logging_level))
-                       level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT,
-                                              SCSI_LOG_MLQUEUE_BITS);
-               /*
-                * if logging is enabled the failure will be printed
-                * in scsi_log_completion(), so avoid duplicate messages
-                */
-               if (!level && !(req->cmd_flags & REQ_QUIET)) {
-                       scsi_print_result(cmd, NULL, FAILED);
-                       if (driver_byte(result) & DRIVER_SENSE)
-                               scsi_print_sense(cmd);
-                       scsi_print_command(cmd);
+               if (!(req->cmd_flags & REQ_QUIET)) {
+                       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;