This patch fixes following deadlock caused by destroying of an FCoE interface with active NPIV ports on that interface.
Call Trace: [<ffffffff814b7e88>] schedule+0x64/0x66 [<ffffffff814b6b4f>] schedule_timeout+0x36/0xe3 [<ffffffff81070c55>] ? update_curr+0xd6/0x110 [<ffffffff81071f6b>] ? hrtick_update+0x1b/0x4d [<ffffffff81072405>] ? dequeue_task_fair+0x1ca/0x1d9 [<ffffffff8106a369>] ? need_resched+0x1e/0x28 [<ffffffff814b7d14>] wait_for_common+0x9b/0xf1 [<ffffffff8106e7be>] ? try_to_wake_up+0x1e0/0x1e0 [<ffffffff814b7e22>] wait_for_completion+0x1d/0x1f [<ffffffff8105ae82>] flush_workqueue+0x116/0x2a1 [<ffffffff8105b357>] drain_workqueue+0x66/0x14c [<ffffffff8105b8ef>] destroy_workqueue+0x1a/0xcf [<ffffffffa009211e>] fc_remove_host+0x154/0x17f [scsi_transport_fc] [<ffffffffa00edbb8>] fcoe_if_destroy+0x184/0x1c9 [fcoe] [<ffffffffa00edc28>] fcoe_destroy_work+0x2b/0x44 [fcoe] [<ffffffff8105a82a>] process_one_work+0x1a8/0x2a4 [<ffffffffa00edbfd>] ? fcoe_if_destroy+0x1c9/0x1c9 [fcoe] [<ffffffff8105c396>] worker_thread+0x1db/0x268 [<ffffffff810604a3>] ? wake_up_bit+0x2a/0x2a [<ffffffff8105c1bb>] ? manage_workers.clone.16+0x1f6/0x1f6 [<ffffffff8105ffd6>] kthread+0x6f/0x77 [<ffffffff814c0304>] kernel_thread_helper+0x4/0x10 [<ffffffff8105ff67>] ? kthread_freezable_should_stop+0x4b/0x4b Call Trace: [<ffffffff814b7e88>] schedule+0x64/0x66 [<ffffffff814b8041>] schedule_preempt_disabled+0xe/0x10 [<ffffffff814b70a1>] __mutex_lock_common.clone.5+0x117/0x17a [<ffffffff814b7117>] __mutex_lock_slowpath+0x13/0x15 [<ffffffff814b6f76>] mutex_lock+0x23/0x37 [<ffffffff8125b890>] ? list_del+0x11/0x30 [<ffffffffa00edc84>] fcoe_vport_destroy+0x43/0x5f [fcoe] [<ffffffffa009130a>] fc_vport_terminate+0x48/0x110 [scsi_transport_fc] [<ffffffffa00913ef>] fc_vport_sched_delete+0x1d/0x79 [scsi_transport_fc] [<ffffffff8105a82a>] process_one_work+0x1a8/0x2a4 [<ffffffffa00913d2>] ? fc_vport_terminate+0x110/0x110 [scsi_transport_fc] [<ffffffff8105c396>] worker_thread+0x1db/0x268 [<ffffffff8105c1bb>] ? manage_workers.clone.16+0x1f6/0x1f6 [<ffffffff8105ffd6>] kthread+0x6f/0x77 [<ffffffff814c0304>] kernel_thread_helper+0x4/0x10 [<ffffffff8105ff67>] ? kthread_freezable_should_stop+0x4b/0x4b [<ffffffff814c0300>] ? gs_change+0x13/0x13 There is no need to grab the fcoe_config_mutex for the NPIV port deletion path; and it can be protected by the physical port's mutex. Hence, removing the fcoe_config_mutex usage from the fcoe_vport_destroy() routine. Also, an additional check has been added to make sure the NPIV port is still present in the physical port's vport list before continuing with destroying of the NPIV port. Signed-off-by: Neerav Parikh <neerav.par...@intel.com> Tested-by: Ross Brattain <ross.b.bratt...@intel.com> --- drivers/scsi/fcoe/fcoe.c | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 666b7ac..ff5e45b 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -2712,14 +2712,25 @@ static int fcoe_vport_destroy(struct fc_vport *vport) struct Scsi_Host *shost = vport_to_shost(vport); struct fc_lport *n_port = shost_priv(shost); struct fc_lport *vn_port = vport->dd_data; + struct fc_lport *v_port; + bool found = false; mutex_lock(&n_port->lp_mutex); - list_del(&vn_port->list); - mutex_unlock(&n_port->lp_mutex); + list_for_each_entry(v_port, &n_port->vports, list) { + if (v_port->vport == vport) { + found = true; + break; + } + } - mutex_lock(&fcoe_config_mutex); + if (!found) { + mutex_unlock(&n_port->lp_mutex); + return -ENOENT; + } + + list_del(&vn_port->list); fcoe_if_destroy(vn_port); - mutex_unlock(&fcoe_config_mutex); + mutex_unlock(&n_port->lp_mutex); return 0; } _______________________________________________ devel mailing list devel@open-fcoe.org https://lists.open-fcoe.org/mailman/listinfo/devel