History

Merge tag 'core-debugobjects-2023-05-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull debugobjects fixes from Thomas Gleixner: "Two fixes for debugobjects: - Prevent the allocation path from waking up kswapd. That's a long standing issue due to the GFP_ATOMIC allocation flag. As debug objects can be invoked from pretty much any context waking kswapd can end up in arbitrary lock chains versus the waitqueue lock - Correct the explicit lockdep wait-type violation in debug_object_fill_pool()" * tag 'core-debugobjects-2023-05-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: debugobjects: Don't wake up kswapd from fill_pool() debugobjects,locking: Annotate debug_object_fill_pool() wait type violation

Linus Torvalds committed 3 years ago

Commit d8f14b82 parents 9bd5386 eb799274 files · +50 −10Browse files

Unified · Split

4 files
  1. include/linux/lockdep.h +14 −0
  2. include/linux/lockdep_types.h +1 −0
  3. kernel/locking/lockdep.c +21 −7
  4. lib/debugobjects.c +14 −3
include/linux/lockdep.h+14−0
@@ -344,6 +344,16 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); · 343 unmodified lines
344#define lockdep_repin_lock(l,c) lock_repin_lock(&(l)->dep_map, (c))344#define lockdep_repin_lock(l,c) lock_repin_lock(&(l)->dep_map, (c))
345#define lockdep_unpin_lock(l,c) lock_unpin_lock(&(l)->dep_map, (c))345#define lockdep_unpin_lock(l,c) lock_unpin_lock(&(l)->dep_map, (c))
346 346
347/*
348 * Must use lock_map_aquire_try() with override maps to avoid
349 * lockdep thinking they participate in the block chain.
350 */
351#define DEFINE_WAIT_OVERRIDE_MAP(_name, _wait_type) \
352 struct lockdep_map _name = { \
353 .name = #_name "-wait-type-override", \
354 .wait_type_inner = _wait_type, \
355 .lock_type = LD_LOCK_WAIT_OVERRIDE, }
356
347#else /* !CONFIG_LOCKDEP */357#else /* !CONFIG_LOCKDEP */
348 358
349static inline void lockdep_init_task(struct task_struct *task)359static inline void lockdep_init_task(struct task_struct *task)
@@ -432,6 +442,9 @@ extern int lockdep_is_held(const void *); · 82 unmodified lines
432#define lockdep_repin_lock(l, c) do { (void)(l); (void)(c); } while (0)442#define lockdep_repin_lock(l, c) do { (void)(l); (void)(c); } while (0)
433#define lockdep_unpin_lock(l, c) do { (void)(l); (void)(c); } while (0)443#define lockdep_unpin_lock(l, c) do { (void)(l); (void)(c); } while (0)
434 444
445#define DEFINE_WAIT_OVERRIDE_MAP(_name, _wait_type) \
446 struct lockdep_map __maybe_unused _name = {}
447
435#endif /* !LOCKDEP */448#endif /* !LOCKDEP */
436 449
437enum xhlock_context_t {450enum xhlock_context_t {
@@ -556,6 +569,7 @@ do { \ · 118 unmodified lines
556#define rwsem_release(l, i) lock_release(l, i)569#define rwsem_release(l, i) lock_release(l, i)
557 570
558#define lock_map_acquire(l) lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_)571#define lock_map_acquire(l) lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_)
572#define lock_map_acquire_try(l) lock_acquire_exclusive(l, 0, 1, NULL, _THIS_IP_)
559#define lock_map_acquire_read(l) lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)573#define lock_map_acquire_read(l) lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
560#define lock_map_acquire_tryread(l) lock_acquire_shared_recursive(l, 0, 1, NULL, _THIS_IP_)574#define lock_map_acquire_tryread(l) lock_acquire_shared_recursive(l, 0, 1, NULL, _THIS_IP_)
561#define lock_map_release(l) lock_release(l, _THIS_IP_)575#define lock_map_release(l) lock_release(l, _THIS_IP_)
include/linux/lockdep_types.h+1−0
@@ -33,6 +33,7 @@ enum lockdep_wait_type { · 32 unmodified lines
33enum lockdep_lock_type {33enum lockdep_lock_type {
34 LD_LOCK_NORMAL = 0, /* normal, catch all */34 LD_LOCK_NORMAL = 0, /* normal, catch all */
35 LD_LOCK_PERCPU, /* percpu */35 LD_LOCK_PERCPU, /* percpu */
36 LD_LOCK_WAIT_OVERRIDE, /* annotation */
36 LD_LOCK_MAX,37 LD_LOCK_MAX,
37};38};
38 39
kernel/locking/lockdep.c+21−7
@@ -2263,6 +2263,9 @@ static inline bool usage_match(struct lock_list *entry, void *mask) · 2262 unmodified lines
2263 2263
2264static inline bool usage_skip(struct lock_list *entry, void *mask)2264static inline bool usage_skip(struct lock_list *entry, void *mask)
2265{2265{
2266 if (entry->class->lock_type == LD_LOCK_NORMAL)
2267 return false;
2268
2266 /*2269 /*
2267 * Skip local_lock() for irq inversion detection.2270 * Skip local_lock() for irq inversion detection.
2268 *2271 *
@@ -2289,14 +2292,16 @@ static inline bool usage_skip(struct lock_list *entry, void *mask) · 20 unmodified lines
2289 * As a result, we will skip local_lock(), when we search for irq2292 * As a result, we will skip local_lock(), when we search for irq
2290 * inversion bugs.2293 * inversion bugs.
2291 */2294 */
2292 if (entry->class->lock_type == LD_LOCK_PERCPU) {2295 if (entry->class->lock_type == LD_LOCK_PERCPU &&
2293 if (DEBUG_LOCKS_WARN_ON(entry->class->wait_type_inner < LD_WAIT_CONFIG))2296 DEBUG_LOCKS_WARN_ON(entry->class->wait_type_inner < LD_WAIT_CONFIG))
2294 return false;2297 return false;
2295 2298
2296 return true;2299 /*
2297 }2300 * Skip WAIT_OVERRIDE for irq inversion detection -- it's not actually
2301 * a lock and only used to override the wait_type.
2302 */
2298 2303
2299 return false;2304 return true;
2300}2305}
2301 2306
2302/*2307/*
@@ -4768,7 +4773,8 @@ static int check_wait_context(struct task_struct *curr, struct held_lock *next) · 2465 unmodified lines
4768 4773
4769 for (; depth < curr->lockdep_depth; depth++) {4774 for (; depth < curr->lockdep_depth; depth++) {
4770 struct held_lock *prev = curr->held_locks + depth;4775 struct held_lock *prev = curr->held_locks + depth;
4771 u8 prev_inner = hlock_class(prev)->wait_type_inner;4776 struct lock_class *class = hlock_class(prev);
4777 u8 prev_inner = class->wait_type_inner;
4772 4778
4773 if (prev_inner) {4779 if (prev_inner) {
4774 /*4780 /*
@@ -4778,6 +4784,14 @@ static int check_wait_context(struct task_struct *curr, struct held_lock *next) · 3 unmodified lines
4778 * Also due to trylocks.4784 * Also due to trylocks.
4779 */4785 */
4780 curr_inner = min(curr_inner, prev_inner);4786 curr_inner = min(curr_inner, prev_inner);
4787
4788 /*
4789 * Allow override for annotations -- this is typically
4790 * only valid/needed for code that only exists when
4791 * CONFIG_PREEMPT_RT=n.
4792 */
4793 if (unlikely(class->lock_type == LD_LOCK_WAIT_OVERRIDE))
4794 curr_inner = prev_inner;
4781 }4795 }
4782 }4796 }
4783 4797
lib/debugobjects.c+14−3
@@ -126,7 +126,7 @@ static const char *obj_states[ODEBUG_STATE_MAX] = { · 125 unmodified lines
126 126
127static void fill_pool(void)127static void fill_pool(void)
128{128{
129 gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;129 gfp_t gfp = __GFP_HIGH | __GFP_NOWARN;
130 struct debug_obj *obj;130 struct debug_obj *obj;
131 unsigned long flags;131 unsigned long flags;
132 132
@@ -591,10 +591,21 @@ static void debug_objects_fill_pool(void) · 458 unmodified lines
591{591{
592 /*592 /*
593 * On RT enabled kernels the pool refill must happen in preemptible593 * On RT enabled kernels the pool refill must happen in preemptible
594 * context:594 * context -- for !RT kernels we rely on the fact that spinlock_t and
595 * raw_spinlock_t are basically the same type and this lock-type
596 * inversion works just fine.
595 */597 */
596 if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible())598 if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible()) {
599 /*
600 * Annotate away the spinlock_t inside raw_spinlock_t warning
601 * by temporarily raising the wait-type to WAIT_SLEEP, matching
602 * the preemptible() condition above.
603 */
604 static DEFINE_WAIT_OVERRIDE_MAP(fill_pool_map, LD_WAIT_SLEEP);
605 lock_map_acquire_try(&fill_pool_map);
597 fill_pool();606 fill_pool();
607 lock_map_release(&fill_pool_map);
608 }
598}609}
599 610
600static void611static void