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 <xieliujie@oppo.com>
Change-Id: I48c057041f9c7b8c5ab0af305f0cd87a039d0447
This commit is contained in:
xieliujie
2021-05-06 20:12:24 +08:00
committed by Suren Baghdasaryan
parent f150653471
commit dc5241048f
3 changed files with 24 additions and 1 deletions

View File

@@ -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_rvh_util_est_update);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_meminfo_proc_show); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_meminfo_proc_show);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_mm); 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_alloc_pages_slowpath);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_print_slabinfo_header); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_print_slabinfo_header);

View File

@@ -47,6 +47,17 @@ DECLARE_HOOK(android_vh_meminfo_proc_show,
DECLARE_HOOK(android_vh_exit_mm, DECLARE_HOOK(android_vh_exit_mm,
TP_PROTO(struct mm_struct *mm), TP_PROTO(struct mm_struct *mm),
TP_ARGS(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, DECLARE_HOOK(android_vh_show_mem,
TP_PROTO(unsigned int filter, nodemask_t *nodemask), TP_PROTO(unsigned int filter, nodemask_t *nodemask),
TP_ARGS(filter, nodemask)); TP_ARGS(filter, nodemask));

View File

@@ -55,7 +55,8 @@
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/mmap.h> #include <trace/events/mmap.h>
#undef CREATE_TRACE_POINTS
#include <trace/hooks/mm.h>
#include "internal.h" #include "internal.h"
#ifndef arch_mmap_check #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 mm_struct *mm = current->mm;
struct vm_area_struct *vma; struct vm_area_struct *vma;
unsigned long length, low_limit, high_limit, gap_start, gap_end; unsigned long length, low_limit, high_limit, gap_start, gap_end;
unsigned long addr;
/* Adjust search length to account for worst case alignment overhead */ /* Adjust search length to account for worst case alignment overhead */
length = info->length + info->align_mask; length = info->length + info->align_mask;
if (length < info->length) if (length < info->length)
return -ENOMEM; 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. * Adjust search limits by the desired length.
* See implementation comment at top of unmapped_area(). * 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.high_limit = arch_get_mmap_base(addr, mm->mmap_base);
info.align_mask = 0; info.align_mask = 0;
info.align_offset = 0; info.align_offset = 0;
trace_android_vh_exclude_reserved_zone(mm, &info);
addr = vm_unmapped_area(&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); addr = vm_unmapped_area(&info);
} }
trace_android_vh_get_unmapped_area_include_reserved_zone(mm, &info, &addr);
return addr; return addr;
} }
#endif #endif