fcst: Fix a potential deadlock

This patch fixes the following lockdep warning:

======================================================
[ INFO: possible circular locking dependency detected ]
3.13.0-rc6-debug+ #5 Tainted: G        W  O
-------------------------------------------------------
rmmod/8653 is trying to acquire lock:
 (scst_tgt_kref){+.+.+.}, at: [<ffffffffa033de6f>] scst_tgt_sysfs_put+0x10f/0x190 [scst]

but task is already holding lock:
 (ft_lport_lock){+.+.+.}, at: [<ffffffffa029d3db>] ft_lport_del+0x1b/0x40 [fcst]

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 (ft_lport_lock){+.+.+.}:
       [<ffffffff8109b4b4>] lock_acquire+0xa4/0x1e0
       [<ffffffff81559837>] mutex_lock_nested+0x77/0x430
       [<ffffffffa029d5a0>] ft_tgt_enable+0x20/0xd0 [fcst]
       [<ffffffffa0335c99>] scst_process_tgt_enable_store+0xe9/0x230 [scst]
       [<ffffffffa0335dfc>] scst_tgt_enable_store_work_fn+0x1c/0x20 [scst]
       [<ffffffffa0338ebc>] scst_process_sysfs_works+0xfc/0x1f0 [scst]
       [<ffffffffa033d180>] sysfs_work_thread_fn+0x120/0x2b0 [scst]
       [<ffffffff81074850>] kthread+0xf0/0x110
       [<ffffffff815663fc>] ret_from_fork+0x7c/0xb0

-> #0 (scst_tgt_kref){+.+.+.}:
       [<ffffffff8109a95b>] __lock_acquire+0x17ab/0x1b10
       [<ffffffff8109b4b4>] lock_acquire+0xa4/0x1e0
       [<ffffffffa03375b9>] scst_kobject_put_and_wait+0x99/0x260 [scst]
       [<ffffffffa033de6f>] scst_tgt_sysfs_put+0x10f/0x190 [scst]
       [<ffffffffa03053dc>] scst_unregister_target+0x15c/0x3c0 [scst]
       [<ffffffffa029c69c>] ft_tport_delete+0x2c/0xa0 [fcst]
       [<ffffffffa029d3ec>] ft_lport_del+0x2c/0x40 [fcst]
       [<ffffffffa023e249>] fc_lport_iterate+0x49/0x80 [libfc]
       [<ffffffffa029d804>] ft_module_exit+0x36/0x832 [fcst]
       [<ffffffff810cd3f2>] SyS_delete_module+0x152/0x1f0
       [<ffffffff815664a9>] system_call_fastpath+0x16/0x1b

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(ft_lport_lock);
                               lock(scst_tgt_kref);
                               lock(ft_lport_lock);
  lock(scst_tgt_kref);

 *** DEADLOCK ***

2 locks held by rmmod/8653:
 #0:  (fc_prov_mutex){+.+.+.}, at: [<ffffffffa023e222>] fc_lport_iterate+0x22/0x80 [libfc]
 #1:  (ft_lport_lock){+.+.+.}, at: [<ffffffffa029d3db>] ft_lport_del+0x1b/0x40 [fcst]

stack backtrace:
CPU: 0 PID: 8653 Comm: rmmod Tainted: G        W  O 3.13.0-rc6-debug+ #5
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
 ffffffff8222ce70 ffff88002efdbb70 ffffffff8155551c ffffffff8222ce70
 ffff88002efdbbb0 ffffffff81552248 ffff88002efdbc00 ffff88002ed0ed88
 ffff88002ed0e6d0 0000000000000002 0000000000000002 ffff88002ed0ed88
Call Trace:
 [<ffffffff8155551c>] dump_stack+0x4e/0x7a
 [<ffffffff81552248>] print_circular_bug+0x200/0x20f
 [<ffffffff8109a95b>] __lock_acquire+0x17ab/0x1b10
 [<ffffffff8109b4b4>] lock_acquire+0xa4/0x1e0
 [<ffffffffa03375b9>] scst_kobject_put_and_wait+0x99/0x260 [scst]
 [<ffffffffa033de6f>] scst_tgt_sysfs_put+0x10f/0x190 [scst]
 [<ffffffffa03053dc>] scst_unregister_target+0x15c/0x3c0 [scst]
 [<ffffffffa029c69c>] ft_tport_delete+0x2c/0xa0 [fcst]
 [<ffffffffa029d3ec>] ft_lport_del+0x2c/0x40 [fcst]
 [<ffffffffa023e249>] fc_lport_iterate+0x49/0x80 [libfc]
 [<ffffffffa029d804>] ft_module_exit+0x36/0x832 [fcst]
 [<ffffffff810cd3f2>] SyS_delete_module+0x152/0x1f0
 [<ffffffff815664a9>] system_call_fastpath+0x16/0x1b


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5196 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2014-01-16 15:23:45 +00:00
parent 6d7fb6343d
commit a57c9d0cee

View File

@@ -608,19 +608,18 @@ int ft_tgt_release(struct scst_tgt *tgt)
return 0;
}
/* Caller must hold a reference on tgt->tgt_kobj. */
int ft_tgt_enable(struct scst_tgt *tgt, bool enable)
{
struct ft_tport *tport;
int ret = 0;
mutex_lock(&ft_lport_lock);
if (enable) {
FT_SESS_DBG("enable tgt %s\n", tgt->tgt_name);
tport = scst_tgt_get_tgt_priv(tgt);
if (tport == NULL) {
ret = -E_TGT_PRIV_NOT_YET_SET;
goto out_unlock;
goto out;
}
tport->enabled = 1;
tport->lport->service_params |= FCP_SPPF_TARG_FCN;
@@ -629,8 +628,7 @@ int ft_tgt_enable(struct scst_tgt *tgt, bool enable)
ft_tgt_release(tgt);
}
out_unlock:
mutex_unlock(&ft_lport_lock);
out:
return ret;
}