Skip to content

Commit

Permalink
[SCSI] zfcp: Invalid locking order
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Swen Schillig authored and James Bottomley committed Feb 10, 2007
1 parent 1996676 commit 6fcc471
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 14 deletions.
2 changes: 1 addition & 1 deletion drivers/s390/scsi/zfcp_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
u32, u32, struct zfcp_sg_list *);
extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long);
extern void zfcp_erp_start_timer(struct zfcp_fsf_req *);
extern int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
extern int zfcp_fsf_status_read(struct zfcp_adapter *, int);
extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *,
unsigned long *, struct zfcp_fsf_req **);
Expand Down
23 changes: 10 additions & 13 deletions drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,28 +176,25 @@ static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
/**
* zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
*/
int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
struct zfcp_fsf_req *request, *tmp;
unsigned long flags;
LIST_HEAD(remove_queue);
unsigned int i, counter;

spin_lock_irqsave(&adapter->req_list_lock, flags);
atomic_set(&adapter->reqs_active, 0);
for (i=0; i<REQUEST_LIST_SIZE; i++) {
if (list_empty(&adapter->req_list[i]))
continue;

counter = 0;
list_for_each_entry_safe(request, tmp,
&adapter->req_list[i], list) {
zfcp_fsf_req_dismiss(adapter, request, counter);
counter++;
}
}
for (i=0; i<REQUEST_LIST_SIZE; i++)
list_splice_init(&adapter->req_list[i], &remove_queue);

spin_unlock_irqrestore(&adapter->req_list_lock, flags);

return 0;
counter = 0;
list_for_each_entry_safe(request, tmp, &remove_queue, list) {
zfcp_fsf_req_dismiss(adapter, request, counter);
counter++;
}
}

/*
Expand Down

0 comments on commit 6fcc471

Please sign in to comment.