mm: report a more useful address for reclaim acquisition

A recent lockdep report included these lines:

[   96.177910] 3 locks held by containerd/770:
[   96.177934]  #0: ffff88810815ea28 (&mm->mmap_lock#2){++++}-{3:3},
at: do_user_addr_fault+0x115/0x770
[   96.177999]  #1: ffffffff82915020 (rcu_read_lock){....}-{1:2}, at:
get_swap_device+0x33/0x140
[   96.178057]  #2: ffffffff82955ba0 (fs_reclaim){+.+.}-{0:0}, at:
__fs_reclaim_acquire+0x5/0x30

While it was not useful to that bug report to know where the reclaim lock
had been acquired, it might be useful under other circumstances.  Allow
the caller of __fs_reclaim_acquire to specify the instruction pointer to
use.

Link: https://lkml.kernel.org/r/20210719185709.1755149-1-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Matthew Wilcox (Oracle) 2021-09-02 14:52:58 -07:00 committed by Linus Torvalds
parent 8c5b3a8ada
commit 4f3eaf452a
3 changed files with 14 additions and 14 deletions

View File

@ -174,13 +174,13 @@ static inline gfp_t current_gfp_context(gfp_t flags)
} }
#ifdef CONFIG_LOCKDEP #ifdef CONFIG_LOCKDEP
extern void __fs_reclaim_acquire(void); extern void __fs_reclaim_acquire(unsigned long ip);
extern void __fs_reclaim_release(void); extern void __fs_reclaim_release(unsigned long ip);
extern void fs_reclaim_acquire(gfp_t gfp_mask); extern void fs_reclaim_acquire(gfp_t gfp_mask);
extern void fs_reclaim_release(gfp_t gfp_mask); extern void fs_reclaim_release(gfp_t gfp_mask);
#else #else
static inline void __fs_reclaim_acquire(void) { } static inline void __fs_reclaim_acquire(unsigned long ip) { }
static inline void __fs_reclaim_release(void) { } static inline void __fs_reclaim_release(unsigned long ip) { }
static inline void fs_reclaim_acquire(gfp_t gfp_mask) { } static inline void fs_reclaim_acquire(gfp_t gfp_mask) { }
static inline void fs_reclaim_release(gfp_t gfp_mask) { } static inline void fs_reclaim_release(gfp_t gfp_mask) { }
#endif #endif

View File

@ -4549,14 +4549,14 @@ static bool __need_reclaim(gfp_t gfp_mask)
return true; return true;
} }
void __fs_reclaim_acquire(void) void __fs_reclaim_acquire(unsigned long ip)
{ {
lock_map_acquire(&__fs_reclaim_map); lock_acquire_exclusive(&__fs_reclaim_map, 0, 0, NULL, ip);
} }
void __fs_reclaim_release(void) void __fs_reclaim_release(unsigned long ip)
{ {
lock_map_release(&__fs_reclaim_map); lock_release(&__fs_reclaim_map, ip);
} }
void fs_reclaim_acquire(gfp_t gfp_mask) void fs_reclaim_acquire(gfp_t gfp_mask)
@ -4565,7 +4565,7 @@ void fs_reclaim_acquire(gfp_t gfp_mask)
if (__need_reclaim(gfp_mask)) { if (__need_reclaim(gfp_mask)) {
if (gfp_mask & __GFP_FS) if (gfp_mask & __GFP_FS)
__fs_reclaim_acquire(); __fs_reclaim_acquire(_RET_IP_);
#ifdef CONFIG_MMU_NOTIFIER #ifdef CONFIG_MMU_NOTIFIER
lock_map_acquire(&__mmu_notifier_invalidate_range_start_map); lock_map_acquire(&__mmu_notifier_invalidate_range_start_map);
@ -4582,7 +4582,7 @@ void fs_reclaim_release(gfp_t gfp_mask)
if (__need_reclaim(gfp_mask)) { if (__need_reclaim(gfp_mask)) {
if (gfp_mask & __GFP_FS) if (gfp_mask & __GFP_FS)
__fs_reclaim_release(); __fs_reclaim_release(_RET_IP_);
} }
} }
EXPORT_SYMBOL_GPL(fs_reclaim_release); EXPORT_SYMBOL_GPL(fs_reclaim_release);

View File

@ -3812,7 +3812,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int highest_zoneidx)
set_task_reclaim_state(current, &sc.reclaim_state); set_task_reclaim_state(current, &sc.reclaim_state);
psi_memstall_enter(&pflags); psi_memstall_enter(&pflags);
__fs_reclaim_acquire(); __fs_reclaim_acquire(_THIS_IP_);
count_vm_event(PAGEOUTRUN); count_vm_event(PAGEOUTRUN);
@ -3938,9 +3938,9 @@ restart:
wake_up_all(&pgdat->pfmemalloc_wait); wake_up_all(&pgdat->pfmemalloc_wait);
/* Check if kswapd should be suspending */ /* Check if kswapd should be suspending */
__fs_reclaim_release(); __fs_reclaim_release(_THIS_IP_);
ret = try_to_freeze(); ret = try_to_freeze();
__fs_reclaim_acquire(); __fs_reclaim_acquire(_THIS_IP_);
if (ret || kthread_should_stop()) if (ret || kthread_should_stop())
break; break;
@ -3992,7 +3992,7 @@ out:
} }
snapshot_refaults(NULL, pgdat); snapshot_refaults(NULL, pgdat);
__fs_reclaim_release(); __fs_reclaim_release(_THIS_IP_);
psi_memstall_leave(&pflags); psi_memstall_leave(&pflags);
set_task_reclaim_state(current, NULL); set_task_reclaim_state(current, NULL);