diff options
author | Robert Love <robert.w.love@intel.com> | 2012-02-10 20:18:41 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 10:25:17 -0500 |
commit | ccefd23ed2d683ad3c0282280e6e6d0b163ad041 (patch) | |
tree | a819e2a95ee58e1ccf7f7537be2407f5d6e7dfd9 /drivers/scsi/fcoe | |
parent | 6f68794c9283bbce3f7c91d3be34cb4f4f6ed960 (diff) |
[SCSI] fcoe: Do not switch context in vport_delete callback
Currently all port deletion is routed though the FCoE
workqueue (fcoe_wq). When fc_remove_host is called on
an N_Port (for example, from fcoe_destroy) the vports
are queued into a FC Transport workqueue. fc_remove_host
flushes that queue and each vport is passed to fcoe's
fcoe_vport_destroy, which simply queues the associated
fcoe_ports for later deletion. This queue cannot be
flushed within the N_Ports destroy path because of
circular locking issues. The result is that the NPIV
ports are destroyed after the N_Port, which is reverse
of how they are created.
This quirk causes fcoe to keep references on the
fcoe_interface shared by each of these ports (N_Port
and NPIV). Changing the ordering such that NPIV ports
are destroyed before the N_Port will allow us to remove
reference counting on the fcoe_interface instances.
This patch simply allows fcoe_vport_destory to destroy
NPIV ports without deferring them to a workqueue context.
This ensures that when fc_remove_host is called the
NPIV ports will be destroyed first before the N_Port and
allows reference counting on the fcoe's fcoe_interface
to be remove in a later patch.
Signed-off-by: Robert Love <robert.w.love@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 449d31ea07bd..5126685ab982 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -2107,20 +2107,14 @@ static void fcoe_destroy_work(struct work_struct *work) | |||
2107 | { | 2107 | { |
2108 | struct fcoe_port *port; | 2108 | struct fcoe_port *port; |
2109 | struct fcoe_interface *fcoe; | 2109 | struct fcoe_interface *fcoe; |
2110 | int npiv = 0; | ||
2111 | 2110 | ||
2112 | port = container_of(work, struct fcoe_port, destroy_work); | 2111 | port = container_of(work, struct fcoe_port, destroy_work); |
2113 | mutex_lock(&fcoe_config_mutex); | 2112 | mutex_lock(&fcoe_config_mutex); |
2114 | 2113 | ||
2115 | /* set if this is an NPIV port */ | ||
2116 | npiv = port->lport->vport ? 1 : 0; | ||
2117 | |||
2118 | fcoe = port->priv; | 2114 | fcoe = port->priv; |
2119 | fcoe_if_destroy(port->lport); | 2115 | fcoe_if_destroy(port->lport); |
2120 | 2116 | ||
2121 | /* Do not tear down the fcoe interface for NPIV port */ | 2117 | fcoe_interface_cleanup(fcoe); |
2122 | if (!npiv) | ||
2123 | fcoe_interface_cleanup(fcoe); | ||
2124 | 2118 | ||
2125 | mutex_unlock(&fcoe_config_mutex); | 2119 | mutex_unlock(&fcoe_config_mutex); |
2126 | } | 2120 | } |
@@ -2691,12 +2685,15 @@ static int fcoe_vport_destroy(struct fc_vport *vport) | |||
2691 | struct Scsi_Host *shost = vport_to_shost(vport); | 2685 | struct Scsi_Host *shost = vport_to_shost(vport); |
2692 | struct fc_lport *n_port = shost_priv(shost); | 2686 | struct fc_lport *n_port = shost_priv(shost); |
2693 | struct fc_lport *vn_port = vport->dd_data; | 2687 | struct fc_lport *vn_port = vport->dd_data; |
2694 | struct fcoe_port *port = lport_priv(vn_port); | ||
2695 | 2688 | ||
2696 | mutex_lock(&n_port->lp_mutex); | 2689 | mutex_lock(&n_port->lp_mutex); |
2697 | list_del(&vn_port->list); | 2690 | list_del(&vn_port->list); |
2698 | mutex_unlock(&n_port->lp_mutex); | 2691 | mutex_unlock(&n_port->lp_mutex); |
2699 | queue_work(fcoe_wq, &port->destroy_work); | 2692 | |
2693 | mutex_lock(&fcoe_config_mutex); | ||
2694 | fcoe_if_destroy(vn_port); | ||
2695 | mutex_unlock(&fcoe_config_mutex); | ||
2696 | |||
2700 | return 0; | 2697 | return 0; |
2701 | } | 2698 | } |
2702 | 2699 | ||