Commit 2d0da2a4 authored by Brian King's avatar Brian King Committed by James Bottomley
Browse files

[SCSI] ibmvfc: Fix hang on module removal



If certain ELS events are received during module removal, after the kthread
is stopped, the rmmod can hang. This fixes the ibmvfc driver so that ELS
events during rmmod are ignored by stopping all device activity prior to
killing the kthread and also changes reinitialization to not attempt a reinit
if the adapter has been taken offline.

Signed-off-by: default avatarBrian King <brking@linux.vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent b3c10489
Loading
Loading
Loading
Loading
+7 −4
Original line number Original line Diff line number Diff line
@@ -521,9 +521,10 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,
static void ibmvfc_reinit_host(struct ibmvfc_host *vhost)
static void ibmvfc_reinit_host(struct ibmvfc_host *vhost)
{
{
	if (vhost->action == IBMVFC_HOST_ACTION_NONE) {
	if (vhost->action == IBMVFC_HOST_ACTION_NONE) {
		if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
			scsi_block_requests(vhost->host);
			scsi_block_requests(vhost->host);
		ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING);
			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
		}
	} else
	} else
		vhost->reinit = 1;
		vhost->reinit = 1;


@@ -3811,10 +3812,12 @@ static int ibmvfc_remove(struct vio_dev *vdev)


	ENTER;
	ENTER;
	ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
	ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
	ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
	ibmvfc_wait_while_resetting(vhost);
	ibmvfc_release_crq_queue(vhost);
	kthread_stop(vhost->work_thread);
	kthread_stop(vhost->work_thread);
	fc_remove_host(vhost->host);
	fc_remove_host(vhost->host);
	scsi_remove_host(vhost->host);
	scsi_remove_host(vhost->host);
	ibmvfc_release_crq_queue(vhost);


	spin_lock_irqsave(vhost->host->host_lock, flags);
	spin_lock_irqsave(vhost->host->host_lock, flags);
	ibmvfc_purge_requests(vhost, DID_ERROR);
	ibmvfc_purge_requests(vhost, DID_ERROR);