diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 92 |
1 files changed, 44 insertions, 48 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 8f45bbc42126..0284ded96bad 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -119,42 +119,40 @@ lpfc_rampup_queue_depth(struct lpfc_hba *phba, | |||
119 | void | 119 | void |
120 | lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | 120 | lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) |
121 | { | 121 | { |
122 | struct lpfc_vport *vport; | 122 | struct lpfc_vport **vports; |
123 | struct Scsi_Host *host; | 123 | struct Scsi_Host *shost; |
124 | struct scsi_device *sdev; | 124 | struct scsi_device *sdev; |
125 | unsigned long new_queue_depth; | 125 | unsigned long new_queue_depth; |
126 | unsigned long num_rsrc_err, num_cmd_success; | 126 | unsigned long num_rsrc_err, num_cmd_success; |
127 | int i; | ||
127 | 128 | ||
128 | num_rsrc_err = atomic_read(&phba->num_rsrc_err); | 129 | num_rsrc_err = atomic_read(&phba->num_rsrc_err); |
129 | num_cmd_success = atomic_read(&phba->num_cmd_success); | 130 | num_cmd_success = atomic_read(&phba->num_cmd_success); |
130 | 131 | ||
131 | spin_lock_irq(&phba->hbalock); | 132 | vports = lpfc_create_vport_work_array(phba); |
132 | list_for_each_entry(vport, &phba->port_list, listentry) { | 133 | if (vports != NULL) |
133 | host = lpfc_shost_from_vport(vport); | 134 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { |
134 | if (!scsi_host_get(host)) | 135 | shost = lpfc_shost_from_vport(vports[i]); |
135 | continue; | 136 | shost_for_each_device(sdev, shost) { |
136 | |||
137 | spin_unlock_irq(&phba->hbalock); | ||
138 | |||
139 | shost_for_each_device(sdev, host) { | ||
140 | new_queue_depth = sdev->queue_depth * num_rsrc_err / | ||
141 | (num_rsrc_err + num_cmd_success); | ||
142 | if (!new_queue_depth) | ||
143 | new_queue_depth = sdev->queue_depth - 1; | ||
144 | else | ||
145 | new_queue_depth = | 137 | new_queue_depth = |
146 | sdev->queue_depth - new_queue_depth; | 138 | sdev->queue_depth * num_rsrc_err / |
147 | 139 | (num_rsrc_err + num_cmd_success); | |
148 | if (sdev->ordered_tags) | 140 | if (!new_queue_depth) |
149 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, | 141 | new_queue_depth = sdev->queue_depth - 1; |
150 | new_queue_depth); | 142 | else |
151 | else | 143 | new_queue_depth = sdev->queue_depth - |
152 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, | 144 | new_queue_depth; |
153 | new_queue_depth); | 145 | if (sdev->ordered_tags) |
146 | scsi_adjust_queue_depth(sdev, | ||
147 | MSG_ORDERED_TAG, | ||
148 | new_queue_depth); | ||
149 | else | ||
150 | scsi_adjust_queue_depth(sdev, | ||
151 | MSG_SIMPLE_TAG, | ||
152 | new_queue_depth); | ||
153 | } | ||
154 | } | 154 | } |
155 | spin_lock_irq(&phba->hbalock); | 155 | lpfc_destroy_vport_work_array(vports); |
156 | scsi_host_put(host); | ||
157 | } | ||
158 | spin_unlock_irq(&phba->hbalock); | 156 | spin_unlock_irq(&phba->hbalock); |
159 | atomic_set(&phba->num_rsrc_err, 0); | 157 | atomic_set(&phba->num_rsrc_err, 0); |
160 | atomic_set(&phba->num_cmd_success, 0); | 158 | atomic_set(&phba->num_cmd_success, 0); |
@@ -163,29 +161,27 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
163 | void | 161 | void |
164 | lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | 162 | lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) |
165 | { | 163 | { |
166 | struct lpfc_vport *vport; | 164 | struct lpfc_vport **vports; |
167 | struct Scsi_Host *host; | 165 | struct Scsi_Host *shost; |
168 | struct scsi_device *sdev; | 166 | struct scsi_device *sdev; |
169 | 167 | int i; | |
170 | spin_lock_irq(&phba->hbalock); | 168 | |
171 | list_for_each_entry(vport, &phba->port_list, listentry) { | 169 | vports = lpfc_create_vport_work_array(phba); |
172 | host = lpfc_shost_from_vport(vport); | 170 | if (vports != NULL) |
173 | if (!scsi_host_get(host)) | 171 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { |
174 | continue; | 172 | shost = lpfc_shost_from_vport(vports[i]); |
175 | 173 | shost_for_each_device(sdev, shost) { | |
176 | spin_unlock_irq(&phba->hbalock); | 174 | if (sdev->ordered_tags) |
177 | shost_for_each_device(sdev, host) { | 175 | scsi_adjust_queue_depth(sdev, |
178 | if (sdev->ordered_tags) | 176 | MSG_ORDERED_TAG, |
179 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, | 177 | sdev->queue_depth+1); |
180 | sdev->queue_depth+1); | 178 | else |
181 | else | 179 | scsi_adjust_queue_depth(sdev, |
182 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, | 180 | MSG_SIMPLE_TAG, |
183 | sdev->queue_depth+1); | 181 | sdev->queue_depth+1); |
182 | } | ||
184 | } | 183 | } |
185 | spin_lock_irq(&phba->hbalock); | 184 | lpfc_destroy_vport_work_array(vports); |
186 | scsi_host_put(host); | ||
187 | } | ||
188 | spin_unlock_irq(&phba->hbalock); | ||
189 | atomic_set(&phba->num_rsrc_err, 0); | 185 | atomic_set(&phba->num_rsrc_err, 0); |
190 | atomic_set(&phba->num_cmd_success, 0); | 186 | atomic_set(&phba->num_cmd_success, 0); |
191 | } | 187 | } |