Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fcc4711 authored by Swen Schillig's avatar Swen Schillig Committed by James Bottomley
Browse files

[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: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 19966769
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -89,7 +89,7 @@ extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
				  u32, u32, struct zfcp_sg_list *);
				  u32, u32, struct zfcp_sg_list *);
extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long);
extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long);
extern void zfcp_erp_start_timer(struct zfcp_fsf_req *);
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_status_read(struct zfcp_adapter *, int);
extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *,
extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *,
			       unsigned long *, struct zfcp_fsf_req **);
			       unsigned long *, struct zfcp_fsf_req **);
+10 −13
Original line number Original line Diff line number Diff line
@@ -176,29 +176,26 @@ static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
/**
/**
 * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
 * 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;
	struct zfcp_fsf_req *request, *tmp;
	unsigned long flags;
	unsigned long flags;
	LIST_HEAD(remove_queue);
	unsigned int i, counter;
	unsigned int i, counter;


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

	spin_unlock_irqrestore(&adapter->req_list_lock, flags);


	counter = 0;
	counter = 0;
		list_for_each_entry_safe(request, tmp,
	list_for_each_entry_safe(request, tmp, &remove_queue, list) {
					 &adapter->req_list[i], list) {
		zfcp_fsf_req_dismiss(adapter, request, counter);
		zfcp_fsf_req_dismiss(adapter, request, counter);
		counter++;
		counter++;
	}
	}
}
}
	spin_unlock_irqrestore(&adapter->req_list_lock, flags);

	return 0;
}


/*
/*
 * function:    zfcp_fsf_req_complete
 * function:    zfcp_fsf_req_complete