aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2007-02-07 07:17:57 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-02-10 14:11:14 -0500
commit6fcc47111ae14f284007e1b9a5002babb01d913c (patch)
tree71fbe20f7c69a7e93b239cc22a13bbc05936d024 /drivers/s390/scsi/zfcp_fsf.c
parent19966769f9fc1968dcf5bffec2e53f7f40100872 (diff)
[SCSI] zfcp: Invalid locking order
Invalid locking order. Kernel hangs after trying to take two locks which are dependend on each other. Introducing temporary variable to free requests. Free lock after requests are copied. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 067f1519eb04..eabf86bb13f5 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -176,28 +176,25 @@ static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
176/** 176/**
177 * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests 177 * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
178 */ 178 */
179int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) 179void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
180{ 180{
181 struct zfcp_fsf_req *request, *tmp; 181 struct zfcp_fsf_req *request, *tmp;
182 unsigned long flags; 182 unsigned long flags;
183 LIST_HEAD(remove_queue);
183 unsigned int i, counter; 184 unsigned int i, counter;
184 185
185 spin_lock_irqsave(&adapter->req_list_lock, flags); 186 spin_lock_irqsave(&adapter->req_list_lock, flags);
186 atomic_set(&adapter->reqs_active, 0); 187 atomic_set(&adapter->reqs_active, 0);
187 for (i=0; i<REQUEST_LIST_SIZE; i++) { 188 for (i=0; i<REQUEST_LIST_SIZE; i++)
188 if (list_empty(&adapter->req_list[i])) 189 list_splice_init(&adapter->req_list[i], &remove_queue);
189 continue; 190
190
191 counter = 0;
192 list_for_each_entry_safe(request, tmp,
193 &adapter->req_list[i], list) {
194 zfcp_fsf_req_dismiss(adapter, request, counter);
195 counter++;
196 }
197 }
198 spin_unlock_irqrestore(&adapter->req_list_lock, flags); 191 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
199 192
200 return 0; 193 counter = 0;
194 list_for_each_entry_safe(request, tmp, &remove_queue, list) {
195 zfcp_fsf_req_dismiss(adapter, request, counter);
196 counter++;
197 }
201} 198}
202 199
203/* 200/*