From ef161f930f466e203cc3dd411f41ac7c63e35cb6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 17 Nov 2019 19:24:43 +0000 Subject: [PATCH] scst: Rework handling of recursive locking Use lockdep_register_key() and lockdep_unregister_key() instead of disabling lockdep checking for certain lock objects. See also Linux kernel commit 108c14858b9e ("locking/lockdep: Add support for dynamic keys"; kernel version v5.1). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8663 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 62 ++-------------------------------------- scst/src/scst_copy_mgr.c | 4 +-- scst/src/scst_lib.c | 25 ++++++++++++---- 3 files changed, 23 insertions(+), 68 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index 0cb988777..118629bb6 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -66,66 +66,6 @@ #include #endif -#ifdef NOLOCKDEP_SUPPORTED -#define spin_lock_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - spin_lock(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define spin_unlock_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - spin_unlock(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define mutex_lock_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - mutex_lock(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define mutex_unlock_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - mutex_unlock(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define down_read_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - down_read(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define up_read_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - up_read(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define down_write_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - down_write(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#define up_write_nolockdep(lock) \ - do { \ - current->nolockdep_call = 1; \ - up_write(lock); \ - current->nolockdep_call = 0; \ - } while (0) -#else -#define spin_lock_nolockdep spin_lock -#define spin_unlock_nolockdep spin_unlock -#define mutex_lock_nolockdep mutex_lock -#define mutex_unlock_nolockdep mutex_unlock -#define down_read_nolockdep down_read -#define up_read_nolockdep up_read -#define down_write_nolockdep down_write -#define up_write_nolockdep up_write -#endif - #ifdef INSIDE_KERNEL_TREE #include #else @@ -2879,6 +2819,7 @@ struct scst_device { /* Device lock */ spinlock_t dev_lock ____cacheline_aligned_in_smp; + struct lock_class_key dev_lock_key; #ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT /* Number of commands associated with this device. */ @@ -3190,6 +3131,7 @@ struct scst_tgt_dev { }; spinlock_t tgt_dev_lock; /* per-session device lock */ + struct lock_class_key tgt_dev_key; /* List of UA's for this device, protected by tgt_dev_lock */ struct list_head UA_list; diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index edae7da66..344b69e37 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -1783,7 +1783,7 @@ bool scst_cm_check_block_all_devs(struct scst_cmd *cmd) #if !defined(__CHECKER__) list_for_each_entry(e, &d->cm_sorted_devs_list, cm_sorted_devs_list_entry) { - spin_lock_nolockdep(&e->cm_fcmd->dev->dev_lock); + spin_lock(&e->cm_fcmd->dev->dev_lock); } #endif @@ -1812,7 +1812,7 @@ bool scst_cm_check_block_all_devs(struct scst_cmd *cmd) #if !defined(__CHECKER__) list_for_each_entry_reverse(e, &d->cm_sorted_devs_list, cm_sorted_devs_list_entry) { - spin_unlock_nolockdep(&e->cm_fcmd->dev->dev_lock); + spin_unlock(&e->cm_fcmd->dev->dev_lock); } #endif diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 4333a9489..fca89fd62 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -2666,8 +2666,8 @@ static void scst_queue_report_luns_changed_UA(struct scst_session *sess, list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { - /* Lockdep triggers here a false positive.. */ - spin_lock_nolockdep(&tgt_dev->tgt_dev_lock); + /* Lockdep reports a false positive here before v5.1. */ + spin_lock(&tgt_dev->tgt_dev_lock); } } #endif @@ -2698,7 +2698,7 @@ static void scst_queue_report_luns_changed_UA(struct scst_session *sess, list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { - spin_unlock_nolockdep(&tgt_dev->tgt_dev_lock); + spin_unlock(&tgt_dev->tgt_dev_lock); } } #endif @@ -4213,6 +4213,8 @@ static void scst_free_device(struct work_struct *work) scst_pr_cleanup(dev); + lockdep_unregister_key(&dev->dev_lock_key); + kfree(dev->virt_name); percpu_ref_exit(&dev->refcnt); kmem_cache_free(scst_dev_cachep, dev); @@ -4256,6 +4258,8 @@ int scst_alloc_device(gfp_t gfp_mask, int nodeid, struct scst_device **out_dev) #endif scst_init_mem_lim(&dev->dev_mem_lim); spin_lock_init(&dev->dev_lock); + lockdep_register_key(&dev->dev_lock_key); + lockdep_set_class(&dev->dev_lock, &dev->dev_lock_key); INIT_LIST_HEAD(&dev->dev_exec_cmd_list); INIT_LIST_HEAD(&dev->blocked_cmd_list); INIT_LIST_HEAD(&dev->dev_tgt_dev_list); @@ -5398,6 +5402,8 @@ static int scst_alloc_add_tgt_dev(struct scst_session *sess, dev->virt_name, (unsigned long long)tgt_dev->lun); spin_lock_init(&tgt_dev->tgt_dev_lock); + lockdep_register_key(&tgt_dev->tgt_dev_key); + lockdep_set_class(&tgt_dev->tgt_dev_lock, &tgt_dev->tgt_dev_key); INIT_LIST_HEAD(&tgt_dev->UA_list); scst_init_order_data(&tgt_dev->tgt_dev_order_data); @@ -5496,6 +5502,8 @@ out_dec_free: out_free_ua: scst_free_all_UA(tgt_dev); + lockdep_unregister_key(&tgt_dev->tgt_dev_key); + kmem_cache_free(scst_tgtd_cachep, tgt_dev); goto out; } @@ -5574,6 +5582,8 @@ static void scst_free_tgt_dev(struct scst_tgt_dev *tgt_dev) scst_tgt_dev_stop_threads(tgt_dev); + lockdep_unregister_key(&tgt_dev->tgt_dev_key); + kmem_cache_free(scst_tgtd_cachep, tgt_dev); percpu_ref_put(&dev->refcnt); @@ -12971,8 +12981,11 @@ again: list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { - /* Lockdep triggers here a false positive.. */ - spin_lock_nolockdep(&tgt_dev->tgt_dev_lock); + /* + * Lockdep reports a false positive here before + * kernel version v5.1. + */ + spin_lock(&tgt_dev->tgt_dev_lock); } } #endif @@ -13046,7 +13059,7 @@ out_unlock: list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { - spin_unlock_nolockdep(&tgt_dev->tgt_dev_lock); + spin_unlock(&tgt_dev->tgt_dev_lock); } } rcu_read_unlock();