scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic
authorJustin Tee <justin.tee@broadcom.com>
Tue, 5 Mar 2024 20:04:55 +0000 (12:04 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sun, 10 Mar 2024 22:56:43 +0000 (18:56 -0400)
Typically when an out of resource CQE status is detected, the
lpfc_ramp_down_queue_handler() logic is called to help reduce I/O load by
reducing an sdev's queue_depth.

However, the current lpfc_rampdown_queue_depth() logic does not help reduce
queue_depth.  num_cmd_success is never updated and is always zero, which
means new_queue_depth will always be set to sdev->queue_depth.  So,
new_queue_depth = sdev->queue_depth - new_queue_depth always sets
new_queue_depth to zero.  And, scsi_change_queue_depth(sdev, 0) is
essentially a no-op.

Change the lpfc_ramp_down_queue_handler() logic to set new_queue_depth
equal to sdev->queue_depth subtracted from number of times num_rsrc_err was
incremented.  If num_rsrc_err is >= sdev->queue_depth, then set
new_queue_depth equal to 1.  Eventually, the frequency of Good_Status
frames will signal SCSI upper layer to auto increase the queue_depth back
to the driver default of 64 via scsi_handle_queue_ramp_up().

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240305200503.57317-5-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_scsi.c

index 30d20d37554f6deb28ce816a7307c41db4ae264a..18cbfd371cccddf67af8ad95c478ec1708ab4590 100644 (file)
@@ -1333,7 +1333,6 @@ struct lpfc_hba {
        struct timer_list fabric_block_timer;
        unsigned long bit_flags;
        atomic_t num_rsrc_err;
-       atomic_t num_cmd_success;
        unsigned long last_rsrc_error_time;
        unsigned long last_ramp_down_time;
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
index e7bfaa0eb8110a955a889407442213ffbe2ab86d..fc77f19547debb3e2dce9efccebd8785e25b90f7 100644 (file)
@@ -167,11 +167,10 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
        struct Scsi_Host  *shost;
        struct scsi_device *sdev;
        unsigned long new_queue_depth;
-       unsigned long num_rsrc_err, num_cmd_success;
+       unsigned long num_rsrc_err;
        int i;
 
        num_rsrc_err = atomic_read(&phba->num_rsrc_err);
-       num_cmd_success = atomic_read(&phba->num_cmd_success);
 
        /*
         * The error and success command counters are global per
@@ -186,20 +185,16 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
                for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
                        shost = lpfc_shost_from_vport(vports[i]);
                        shost_for_each_device(sdev, shost) {
-                               new_queue_depth =
-                                       sdev->queue_depth * num_rsrc_err /
-                                       (num_rsrc_err + num_cmd_success);
-                               if (!new_queue_depth)
-                                       new_queue_depth = sdev->queue_depth - 1;
+                               if (num_rsrc_err >= sdev->queue_depth)
+                                       new_queue_depth = 1;
                                else
                                        new_queue_depth = sdev->queue_depth -
-                                                               new_queue_depth;
+                                               num_rsrc_err;
                                scsi_change_queue_depth(sdev, new_queue_depth);
                        }
                }
        lpfc_destroy_vport_work_array(phba, vports);
        atomic_set(&phba->num_rsrc_err, 0);
-       atomic_set(&phba->num_cmd_success, 0);
 }
 
 /**