mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-03 22:06:25 +00:00
scst_sysfs: Trigger a lockdep complaint if sysfs work
could trigger a deadlock This patch causes lockdep to complain if sysfs work could trigger a deadlock. As an example, for the patch below the following lockdep complaint is generated: ====================================================== [ INFO: possible circular locking dependency detected ] 3.12.0-rc7-dbg+ #5 Tainted: GF O ------------------------------------------------------- scst_mgmtd/7527 is trying to acquire lock: (scst_tgt_dev){+.+.+.}, at: [<ffffffffa01f9365>] scst_tgt_dev_sysfs_del+0x105/0x1a0 [scst] but task is already holding lock: (&scst_mutex){+.+.+.}, at: [<ffffffffa01eaa46>] scst_free_session+0x56/0x2c0 [scst] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&scst_mutex){+.+.+.}: [<ffffffff810be983>] lock_acquire+0x93/0x150 [<ffffffff81619617>] mutex_lock_interruptible_nested+0x77/0x500 [<ffffffffa01f1f9f>] scst_tgt_dev_process_thread_pid_show+0x5f/0x120 [scst] [<ffffffffa01f38d6>] scst_process_sysfs_works+0xe6/0x1d0 [scst] [<ffffffffa01f7af0>] sysfs_work_thread_fn+0x120/0x2b0 [scst] [<ffffffff8107482a>] kthread+0xea/0xf0 [<ffffffff81625f6c>] ret_from_fork+0x7c/0xb0 -> #0 (scst_tgt_dev){+.+.+.}: [<ffffffff810bdc8a>] __lock_acquire+0x14fa/0x1a60 [<ffffffff810be983>] lock_acquire+0x93/0x150 [<ffffffffa01f20df>] scst_kobject_put_and_wait+0x6f/0x140 [scst] [<ffffffffa01f9365>] scst_tgt_dev_sysfs_del+0x105/0x1a0 [scst] [<ffffffffa01e9114>] scst_free_tgt_dev+0x84/0x210 [scst] [<ffffffffa01ea80b>] scst_sess_free_tgt_devs+0x6b/0x100 [scst] [<ffffffffa01eaa4e>] scst_free_session+0x5e/0x2c0 [scst] [<ffffffffa01ead4e>] scst_free_session_callback+0x9e/0x170 [scst] [<ffffffffa01d5a9a>] scst_global_mgmt_thread+0x24a/0x550 [scst] [<ffffffff8107482a>] kthread+0xea/0xf0 [<ffffffff81625f6c>] ret_from_fork+0x7c/0xb0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&scst_mutex); lock(scst_tgt_dev); lock(&scst_mutex); lock(scst_tgt_dev); *** DEADLOCK *** 1 lock held by scst_mgmtd/7527: #0: (&scst_mutex){+.+.+.}, at: [<ffffffffa01eaa46>] scst_free_session+0x56/0x2c0 [scst] stack backtrace: CPU: 1 PID: 7527 Comm: scst_mgmtd Tainted: GF O 3.12.0-rc7-dbg+ #5 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013 ffffffff822efd40 ffff88007b7c1ac8 ffffffff8161464a ffffffff822efd40 ffff88007b7c1b08 ffffffff81610d02 ffff88007b7c1b60 ffff8800692748c0 0000000000000000 ffff880069274898 ffff880069274120 ffff8800692748c0 Call Trace: [<ffffffff8161464a>] dump_stack+0x4e/0x82 [<ffffffff81610d02>] print_circular_bug+0x201/0x210 [<ffffffff810bdc8a>] __lock_acquire+0x14fa/0x1a60 [<ffffffff810be983>] lock_acquire+0x93/0x150 [<ffffffffa01f9365>] ? scst_tgt_dev_sysfs_del+0x105/0x1a0 [scst] [<ffffffffa01f20df>] scst_kobject_put_and_wait+0x6f/0x140 [scst] [<ffffffffa01f9365>] ? scst_tgt_dev_sysfs_del+0x105/0x1a0 [scst] [<ffffffffa01f9365>] scst_tgt_dev_sysfs_del+0x105/0x1a0 [scst] [<ffffffffa01e9114>] scst_free_tgt_dev+0x84/0x210 [scst] [<ffffffffa01ea80b>] scst_sess_free_tgt_devs+0x6b/0x100 [scst] [<ffffffffa01eaa4e>] scst_free_session+0x5e/0x2c0 [scst] [<ffffffffa01ead4e>] scst_free_session_callback+0x9e/0x170 [scst] [<ffffffffa01d5a9a>] scst_global_mgmt_thread+0x24a/0x550 [scst] [<ffffffff81075850>] ? wake_up_atomic_t+0x30/0x30 [<ffffffffa01d5850>] ? scst_register_session_non_gpl+0x20/0x20 [scst] [<ffffffff8107482a>] kthread+0xea/0xf0 [<ffffffff81074740>] ? kthread_create_on_node+0x140/0x140 [<ffffffff81625f6c>] ret_from_fork+0x7c/0xb0 [<ffffffff81074740>] ? kthread_create_on_node+0x140/0x140 git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5095 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
+14
-1
@@ -4211,7 +4211,8 @@ struct sysfs_ops *scst_sysfs_get_sysfs_ops(void);
|
||||
#endif
|
||||
|
||||
void scst_kobject_put_and_wait(struct kobject *kobj, const char *category,
|
||||
struct completion *c);
|
||||
struct completion *c,
|
||||
struct lockdep_map *dep_map);
|
||||
|
||||
/*
|
||||
* Returns target driver's root sysfs kobject.
|
||||
@@ -4481,6 +4482,12 @@ struct scst_sysfs_work_item {
|
||||
int (*sysfs_work_fn)(struct scst_sysfs_work_item *work);
|
||||
struct completion sysfs_work_done;
|
||||
char *buf;
|
||||
/*
|
||||
* If the caller of scst_sysfs_queue_wait_work() holds a reference on
|
||||
* a kobject, must point at the lockdep_map structure associated with
|
||||
* that kobject.
|
||||
*/
|
||||
struct lockdep_map *dep_map;
|
||||
|
||||
union {
|
||||
struct scst_dev_type *devt;
|
||||
@@ -4519,6 +4526,12 @@ int scst_sysfs_queue_wait_work(struct scst_sysfs_work_item *work);
|
||||
void scst_sysfs_work_get(struct scst_sysfs_work_item *work);
|
||||
void scst_sysfs_work_put(struct scst_sysfs_work_item *work);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
extern struct lockdep_map scst_dev_dep_map;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
char *scst_get_next_lexem(char **token_str);
|
||||
|
||||
Reference in New Issue
Block a user