diff options
| author | Yin Fengwei <[email protected]> | 2022-12-23 13:52:07 +0000 |
|---|---|---|
| committer | Andrew Morton <[email protected]> | 2023-01-19 01:12:50 +0000 |
| commit | 81e506bec9be1eceaf5a2c654e28ba5176ef48d8 (patch) | |
| tree | 168c884e263e7038c53906665a5f19b39c5fa711 /fs/jbd2/commit.c | |
| parent | mm/page_reporting: replace rcu_access_pointer() with rcu_dereference_protected() (diff) | |
| download | kernel-81e506bec9be1eceaf5a2c654e28ba5176ef48d8.tar.gz kernel-81e506bec9be1eceaf5a2c654e28ba5176ef48d8.zip | |
mm/thp: check and bail out if page in deferred queue already
Kernel build regression with LLVM was reported here:
https://lore.kernel.org/all/Y1GCYXGtEVZbcv%[email protected]/ with
commit f35b5d7d676e ("mm: align larger anonymous mappings on THP
boundaries"). And the commit f35b5d7d676e was reverted.
It turned out the regression is related with madvise(MADV_DONTNEED)
was used by ld.lld. But with none PMD_SIZE aligned parameter len.
trace-bpfcc captured:
531607 531732 ld.lld do_madvise.part.0 start: 0x7feca9000000, len: 0x7fb000, behavior: 0x4
531607 531793 ld.lld do_madvise.part.0 start: 0x7fec86a00000, len: 0x7fb000, behavior: 0x4
If the underneath physical page is THP, the madvise(MADV_DONTNEED) can
trigger split_queue_lock contention raised significantly. perf showed
following data:
14.85% 0.00% ld.lld [kernel.kallsyms] [k]
entry_SYSCALL_64_after_hwframe
11.52%
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_madvise
do_madvise.part.0
zap_page_range
unmap_single_vma
unmap_page_range
page_remove_rmap
deferred_split_huge_page
__lock_text_start
native_queued_spin_lock_slowpath
If THP can't be removed from rmap as whole THP, partial THP will be
removed from rmap by removing sub-pages from rmap. Even the THP head page
is added to deferred queue already, the split_queue_lock will be acquired
and check whether the THP head page is in the queue already. Thus, the
contention of split_queue_lock is raised.
Before acquire split_queue_lock, check and bail out early if the THP
head page is in the queue already. The checking without holding
split_queue_lock could race with deferred_split_scan, but it doesn't
impact the correctness here.
Test result of building kernel with ld.lld:
commit 7b5a0b664ebe (parent commit of f35b5d7d676e):
time -f "\t%E real,\t%U user,\t%S sys" make LD=ld.lld -skj96 allmodconfig all
6:07.99 real, 26367.77 user, 5063.35 sys
commit f35b5d7d676e:
time -f "\t%E real,\t%U user,\t%S sys" make LD=ld.lld -skj96 allmodconfig all
7:22.15 real, 26235.03 user, 12504.55 sys
commit f35b5d7d676e with the fixing patch:
time -f "\t%E real,\t%U user,\t%S sys" make LD=ld.lld -skj96 allmodconfig all
6:08.49 real, 26520.15 user, 5047.91 sys
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Yin Fengwei <[email protected]>
Tested-by: Nathan Chancellor <[email protected]>
Acked-by: David Rientjes <[email protected]>
Reviewed-by: "Huang, Ying" <[email protected]>
Cc: Feng Tang <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: Xing Zhengjun <[email protected]>
Cc: Yang Shi <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Diffstat (limited to 'fs/jbd2/commit.c')
0 files changed, 0 insertions, 0 deletions
