mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-23 21:51:27 +00:00
In some cases SCST needs to take multiple locks recursivly, e.g. to lock all tgt_devs in a session. For this case SCST takes those locks in their current sort order, e.g. by LUN for tgt_devs, then releases in the opposite order. Unfortunately, lockdep complains on such actions as recursive locking, then disables itself. The disabling itself action is the most unpleasant one leading to lockdep being useless after this point. Unfortunately, nested locking annotations can't help, because after free, then alloc again, or after LUN change (in case of tgt_devs) order of locks can change. So, this patch implements a way to annotate some lock and unlock actions as "no lockdep", so lockdep will not track them. It contains related kernel patches for some kernels. This is a debug aid only useful only with lockdep enabled kernels. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7065 d57e44dd-8a1f-0410-8b47-8ef2f437770f
117 lines
3.3 KiB
Diff
117 lines
3.3 KiB
Diff
=== modified file 'include/linux/lockdep.h'
|
|
--- old/include/linux/lockdep.h 2012-08-08 02:57:29 +0000
|
|
+++ new/include/linux/lockdep.h 2012-08-28 21:26:26 +0000
|
|
@@ -355,7 +355,7 @@ extern void lockdep_set_current_reclaim_
|
|
extern void lockdep_clear_current_reclaim_state(void);
|
|
extern void lockdep_trace_alloc(gfp_t mask);
|
|
|
|
-# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0,
|
|
+# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .nolockdep_call = 0,
|
|
|
|
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
|
|
|
|
|
|
=== modified file 'include/linux/sched.h'
|
|
--- old/include/linux/sched.h 2012-08-08 02:57:29 +0000
|
|
+++ new/include/linux/sched.h 2012-08-28 22:49:36 +0000
|
|
@@ -1454,6 +1454,9 @@ struct task_struct {
|
|
# define MAX_LOCK_DEPTH 48UL
|
|
u64 curr_chain_key;
|
|
int lockdep_depth;
|
|
+# define NOLOCKDEP_SUPPORTED 1
|
|
+ unsigned int nolockdep_call:1;
|
|
+ unsigned int nolockdep_call_irq_saved:1;
|
|
unsigned int lockdep_recursion;
|
|
struct held_lock held_locks[MAX_LOCK_DEPTH];
|
|
gfp_t lockdep_reclaim_gfp;
|
|
|
|
=== modified file 'kernel/lockdep.c'
|
|
--- old/kernel/lockdep.c 2012-08-08 02:57:29 +0000
|
|
+++ new/kernel/lockdep.c 2012-08-28 23:02:47 +0000
|
|
@@ -3547,9 +3547,11 @@ void lock_acquire(struct lockdep_map *lo
|
|
if (unlikely(current->lockdep_recursion))
|
|
return;
|
|
|
|
+ if (unlikely(current->nolockdep_call))
|
|
+ return;
|
|
+
|
|
raw_local_irq_save(flags);
|
|
check_flags(flags);
|
|
-
|
|
current->lockdep_recursion = 1;
|
|
trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
|
|
__lock_acquire(lock, subclass, trylock, read, check,
|
|
@@ -3567,6 +3569,9 @@ void lock_release(struct lockdep_map *lo
|
|
if (unlikely(current->lockdep_recursion))
|
|
return;
|
|
|
|
+ if (unlikely(current->nolockdep_call))
|
|
+ return;
|
|
+
|
|
raw_local_irq_save(flags);
|
|
check_flags(flags);
|
|
current->lockdep_recursion = 1;
|
|
@@ -3760,6 +3765,9 @@ void lock_contended(struct lockdep_map *
|
|
if (unlikely(current->lockdep_recursion))
|
|
return;
|
|
|
|
+ if (unlikely(current->nolockdep_call))
|
|
+ return;
|
|
+
|
|
raw_local_irq_save(flags);
|
|
check_flags(flags);
|
|
current->lockdep_recursion = 1;
|
|
@@ -3780,6 +3788,9 @@ void lock_acquired(struct lockdep_map *l
|
|
if (unlikely(current->lockdep_recursion))
|
|
return;
|
|
|
|
+ if (unlikely(current->nolockdep_call))
|
|
+ return;
|
|
+
|
|
raw_local_irq_save(flags);
|
|
check_flags(flags);
|
|
current->lockdep_recursion = 1;
|
|
|
|
=== modified file 'kernel/softirq.c'
|
|
--- old/kernel/softirq.c 2012-08-08 02:57:29 +0000
|
|
+++ new/kernel/softirq.c 2012-08-28 23:23:07 +0000
|
|
@@ -296,6 +296,18 @@ void irq_enter(void)
|
|
{
|
|
int cpu = smp_processor_id();
|
|
|
|
+#ifdef CONFIG_LOCKDEP
|
|
+ if (unlikely(current->nolockdep_call)) {
|
|
+ unsigned long flags;
|
|
+ local_irq_save(flags);
|
|
+ if (current->nolockdep_call) {
|
|
+ current->nolockdep_call_irq_saved = 1;
|
|
+ current->nolockdep_call = 0;
|
|
+ }
|
|
+ local_irq_restore(flags);
|
|
+ }
|
|
+#endif
|
|
+
|
|
rcu_irq_enter();
|
|
if (is_idle_task(current) && !in_interrupt()) {
|
|
/*
|
|
@@ -344,6 +356,18 @@ void irq_exit(void)
|
|
#endif
|
|
rcu_irq_exit();
|
|
sched_preempt_enable_no_resched();
|
|
+
|
|
+#ifdef CONFIG_LOCKDEP
|
|
+ if (unlikely(current->nolockdep_call_irq_saved)) {
|
|
+ unsigned long flags;
|
|
+ local_irq_save(flags);
|
|
+ if (current->nolockdep_call_irq_saved) {
|
|
+ current->nolockdep_call_irq_saved = 0;
|
|
+ current->nolockdep_call = 1;
|
|
+ }
|
|
+ local_irq_restore(flags);
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
/*
|
|
|