aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/lockdep.h8
-rw-r--r--kernel/lockdep.c33
-rw-r--r--kernel/sched.c2
3 files changed, 43 insertions, 0 deletions
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 12aabfcb45f6..a6d5e5e4d084 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -296,6 +296,10 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
296extern void lock_release(struct lockdep_map *lock, int nested, 296extern void lock_release(struct lockdep_map *lock, int nested,
297 unsigned long ip); 297 unsigned long ip);
298 298
299#define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map)
300
301extern int lock_is_held(struct lockdep_map *lock);
302
299extern void lock_set_class(struct lockdep_map *lock, const char *name, 303extern void lock_set_class(struct lockdep_map *lock, const char *name,
300 struct lock_class_key *key, unsigned int subclass, 304 struct lock_class_key *key, unsigned int subclass,
301 unsigned long ip); 305 unsigned long ip);
@@ -314,6 +318,8 @@ extern void lockdep_trace_alloc(gfp_t mask);
314 318
315#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) 319#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
316 320
321#define lockdep_assert_held(l) WARN_ON(debug_locks && !lockdep_is_held(l))
322
317#else /* !LOCKDEP */ 323#else /* !LOCKDEP */
318 324
319static inline void lockdep_off(void) 325static inline void lockdep_off(void)
@@ -358,6 +364,8 @@ struct lock_class_key { };
358 364
359#define lockdep_depth(tsk) (0) 365#define lockdep_depth(tsk) (0)
360 366
367#define lockdep_assert_held(l) do { } while (0)
368
361#endif /* !LOCKDEP */ 369#endif /* !LOCKDEP */
362 370
363#ifdef CONFIG_LOCK_STAT 371#ifdef CONFIG_LOCK_STAT
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 4b6cebe8ab31..28914a509914 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -3059,6 +3059,19 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
3059 check_chain_key(curr); 3059 check_chain_key(curr);
3060} 3060}
3061 3061
3062static int __lock_is_held(struct lockdep_map *lock)
3063{
3064 struct task_struct *curr = current;
3065 int i;
3066
3067 for (i = 0; i < curr->lockdep_depth; i++) {
3068 if (curr->held_locks[i].instance == lock)
3069 return 1;
3070 }
3071
3072 return 0;
3073}
3074
3062/* 3075/*
3063 * Check whether we follow the irq-flags state precisely: 3076 * Check whether we follow the irq-flags state precisely:
3064 */ 3077 */
@@ -3160,6 +3173,26 @@ void lock_release(struct lockdep_map *lock, int nested,
3160} 3173}
3161EXPORT_SYMBOL_GPL(lock_release); 3174EXPORT_SYMBOL_GPL(lock_release);
3162 3175
3176int lock_is_held(struct lockdep_map *lock)
3177{
3178 unsigned long flags;
3179 int ret = 0;
3180
3181 if (unlikely(current->lockdep_recursion))
3182 return ret;
3183
3184 raw_local_irq_save(flags);
3185 check_flags(flags);
3186
3187 current->lockdep_recursion = 1;
3188 ret = __lock_is_held(lock);
3189 current->lockdep_recursion = 0;
3190 raw_local_irq_restore(flags);
3191
3192 return ret;
3193}
3194EXPORT_SYMBOL_GPL(lock_is_held);
3195
3163void lockdep_set_current_reclaim_state(gfp_t gfp_mask) 3196void lockdep_set_current_reclaim_state(gfp_t gfp_mask)
3164{ 3197{
3165 current->lockdep_reclaim_gfp = gfp_mask; 3198 current->lockdep_reclaim_gfp = gfp_mask;
diff --git a/kernel/sched.c b/kernel/sched.c
index 1b59e265273b..2c75f7daa439 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6609,6 +6609,8 @@ int cond_resched_lock(spinlock_t *lock)
6609 int resched = should_resched(); 6609 int resched = should_resched();
6610 int ret = 0; 6610 int ret = 0;
6611 6611
6612 lockdep_assert_held(lock);
6613
6612 if (spin_needbreak(lock) || resched) { 6614 if (spin_needbreak(lock) || resched) {
6613 spin_unlock(lock); 6615 spin_unlock(lock);
6614 if (resched) 6616 if (resched)