2 * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
14 static spinlock_t __lock
= SPIN_LOCK_UNLOCKED
;
15 static int ldep_enabled
;
21 spin_lock_intsave(&__lock
, &mask
);
23 spin_unlock_intrestore(&__lock
, mask
);
26 static int __get_stack_slot()
30 if (current
->nr_locks
== LDEP_STACK_SIZE
) {
31 sclp_msg("task '%s' exceeded the number of tracked "
32 "locks (%d)! disabling ldep!\n", current
->name
,
40 static void ldep_warn_head(char *lockname
, void *addr
)
42 sclp_msg("task '%s' is trying to acquire lock:\n", current
->name
);
43 sclp_msg(" (%s), at: %p\n\n", lockname
, addr
);
46 static void ldep_warn_recursive(char *lockname
, void *addr
, struct held_lock
*held
)
48 sclp_msg("[INFO: possible recursive locking detected]\n");
50 ldep_warn_head(lockname
, addr
);
52 sclp_msg("but task is already holding lock:\n\n");
53 sclp_msg(" (%s), at: %p\n\n", held
->lockname
, held
->ra
);
56 static void print_held_locks()
58 struct held_lock
*cur
;
61 sclp_msg("\nlocks currently held:\n");
62 for(i
=0; i
<current
->nr_locks
; i
++) {
63 cur
= ¤t
->lock_stack
[i
];
64 sclp_msg(" #%d: (%s), at %p\n", i
, cur
->lockname
, cur
->ra
);
68 void ldep_lock(void *lock
, struct lock_class
*c
, char *lockname
)
70 void *ra
= __builtin_return_address(0);
71 struct held_lock
*cur
;
77 spin_lock_intsave(&__lock
, &mask
);
82 if (current
->nr_locks
) {
83 /* check for recursive locking */
84 for(i
=0; i
<current
->nr_locks
; i
++) {
85 cur
= ¤t
->lock_stack
[i
];
89 ldep_warn_recursive(lockname
, ra
, cur
);
95 /* ok, no issues, add the lock we're trying to get to the stack */
96 if (__get_stack_slot())
99 cur
= ¤t
->lock_stack
[current
->nr_locks
-1];
102 cur
->lockname
= lockname
;
107 spin_unlock_intrestore(&__lock
, mask
);
110 void ldep_unlock(void *lock
, char *lockname
)
112 void *ra
= __builtin_return_address(0);
113 struct held_lock
*cur
;
118 spin_lock_intsave(&__lock
, &mask
);
123 for(i
=0; i
<current
->nr_locks
; i
++) {
124 cur
= ¤t
->lock_stack
[i
];
125 if (cur
->lock
== lock
)
129 sclp_msg("task '%s' is trying to release lock it doesn't have:\n",
131 sclp_msg(" (%s), at %p\n", lockname
, ra
);
139 if (i
!= current
->nr_locks
-1)
140 memcpy(¤t
->lock_stack
[i
],
141 ¤t
->lock_stack
[i
+1],
142 current
->nr_locks
- i
- 1);
148 spin_unlock_intrestore(&__lock
, mask
);
153 void *ra
= __builtin_return_address(0);
157 spin_lock_intsave(&__lock
, &mask
);
162 if (!current
->nr_locks
)
165 sclp_msg("task '%s' is holding a lock when it shouldn't have:\n",
167 sclp_msg(" at %p\n", ra
);
174 spin_unlock_intrestore(&__lock
, mask
);