From dc5241048fe9229ddfc784c820f04fabf8c086ef Mon Sep 17 00:00:00 2001 From: xieliujie Date: Thu, 6 May 2021 20:12:24 +0800 Subject: [PATCH] ANDROID: vendor_hooks: Add hooks for reducing virtual address fragmentation When running 32-bit apps for a long time, virtual address becomes fragmented which can lead to allocation failures when a large virtually-contiguous area is requested. Add hooks to implement pools to cluster together small-sized virtual address mappings. Add hooks to implement reserved virtual address zone with usage restrictions controlled by vendor hooks. These hooks help in controlling virtual address space fragmentation. Bug: 187259935 Signed-off-by: xieliujie Change-Id: I48c057041f9c7b8c5ab0af305f0cd87a039d0447 --- drivers/android/vendor_hooks.c | 3 +++ include/trace/hooks/mm.h | 11 +++++++++++ mm/mmap.c | 11 ++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index f25b35274926..11b759a47ae5 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -231,6 +231,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_module_permit_after_init); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_util_est_update); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_meminfo_proc_show); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_mm); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_unmapped_area_from_anti_fragment_pool); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exclude_reserved_zone); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_unmapped_area_include_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_print_slabinfo_header); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index d93ecdd22f19..7a17a8440f8b 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -47,6 +47,17 @@ DECLARE_HOOK(android_vh_meminfo_proc_show, DECLARE_HOOK(android_vh_exit_mm, TP_PROTO(struct mm_struct *mm), TP_ARGS(mm)); +DECLARE_HOOK(android_vh_get_unmapped_area_from_anti_fragment_pool, + TP_PROTO(struct mm_struct *mm, struct vm_unmapped_area_info *info, + unsigned long *addr), + TP_ARGS(mm, info, addr)); +DECLARE_HOOK(android_vh_exclude_reserved_zone, + TP_PROTO(struct mm_struct *mm, struct vm_unmapped_area_info *info), + TP_ARGS(mm, info)); +DECLARE_HOOK(android_vh_get_unmapped_area_include_reserved_zone, + TP_PROTO(struct mm_struct *mm, struct vm_unmapped_area_info *info, + unsigned long *addr), + TP_ARGS(mm, info, addr)); DECLARE_HOOK(android_vh_show_mem, TP_PROTO(unsigned int filter, nodemask_t *nodemask), TP_ARGS(filter, nodemask)); diff --git a/mm/mmap.c b/mm/mmap.c index 1798e6c9d97a..9e95b894190a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -55,7 +55,8 @@ #define CREATE_TRACE_POINTS #include - +#undef CREATE_TRACE_POINTS +#include #include "internal.h" #ifndef arch_mmap_check @@ -2093,12 +2094,17 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned long length, low_limit, high_limit, gap_start, gap_end; + unsigned long addr; /* Adjust search length to account for worst case alignment overhead */ length = info->length + info->align_mask; if (length < info->length) return -ENOMEM; + trace_android_vh_get_unmapped_area_from_anti_fragment_pool(mm, info, &addr); + if (addr) + return addr; + /* * Adjust search limits by the desired length. * See implementation comment at top of unmapped_area(). @@ -2301,6 +2307,7 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, info.high_limit = arch_get_mmap_base(addr, mm->mmap_base); info.align_mask = 0; info.align_offset = 0; + trace_android_vh_exclude_reserved_zone(mm, &info); addr = vm_unmapped_area(&info); /* @@ -2317,6 +2324,8 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, addr = vm_unmapped_area(&info); } + trace_android_vh_get_unmapped_area_include_reserved_zone(mm, &info, &addr); + return addr; } #endif