aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-08-02 11:09:51 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-08-01 13:18:23 -0400
commit549e55cd2a1b83ea45ac17fb6c309654a3d371a4 (patch)
tree0abf10a28b177e129932c62b3b94994ce4f3aadb /drivers/scsi/lpfc/lpfc_scsi.c
parenta58cbd5212fff2d4bba0bf58e778f02069597294 (diff)
[SCSI] lpfc 8.2.2 : Fix locking around HBA's port_list
Cleans up a lot of bad behaviors that have been in this area a while Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c92
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,
119void 119void
120lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) 120lpfc_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)
163void 161void
164lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) 162lpfc_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}