ANDROID: mm: gup: vendor hook in GUP friends

The page pinning causes CMA allocation long latency until the process
held the refcont is scheduled in and then released the refcount, which
introduces CMA allocaiton failure.

To overcome the issue, add vendor hooks to migrate the target page of
GUP out of CMA area.

Bug: 218731671
Signed-off-by: Minchan Kim <minchan@google.com>
Change-Id: I5ebf491531d0bfee96ebee83919f22e34ee1d41b
This commit is contained in:
Minchan Kim
2022-03-09 11:26:56 -08:00
committed by Todd Kjos
parent 0375b0d297
commit aea946bdf0
3 changed files with 55 additions and 0 deletions

View File

@@ -72,6 +72,7 @@
#include <trace/hooks/ipv6.h>
#include <trace/hooks/sound.h>
#include <trace/hooks/snd_compr.h>
#include <trace/hooks/gup.h>
/*
* Export tracepoints that act as a bare tracehook (ie: have no trace event
@@ -382,3 +383,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_enable_thermal_power_throttle);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_thermal_power_cap);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_thermal_zone_device);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_modify_src_caps);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_grab_compound_head);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh___get_user_pages_remote);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_user_pages);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_internal_get_user_pages_fast);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pin_user_pages);

34
include/trace/hooks/gup.h Normal file
View File

@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM gup
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_GUP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_GUP_H
#include <linux/tracepoint.h>
#include <trace/hooks/vendor_hooks.h>
struct page;
DECLARE_HOOK(android_vh_try_grab_compound_head,
TP_PROTO(struct page *page, int refs, unsigned int flags, bool *ret),
TP_ARGS(page, refs, flags, ret));
DECLARE_HOOK(android_vh___get_user_pages_remote,
TP_PROTO(int *locked, unsigned int *gup_flags),
TP_ARGS(locked, gup_flags));
DECLARE_HOOK(android_vh_get_user_pages,
TP_PROTO(unsigned int *gup_flags),
TP_ARGS(gup_flags));
DECLARE_HOOK(android_vh_internal_get_user_pages_fast,
TP_PROTO(unsigned int *gup_flags),
TP_ARGS(gup_flags));
DECLARE_HOOK(android_vh_pin_user_pages,
TP_PROTO(unsigned int *gup_flags),
TP_ARGS(gup_flags));
#endif /* _TRACE_HOOK_GUP_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@@ -25,6 +25,9 @@
#include "internal.h"
#undef CREATE_TRACE_POINTS
#include <trace/hooks/gup.h>
struct follow_page_context {
struct dev_pagemap *pgmap;
unsigned int page_mask;
@@ -116,6 +119,12 @@ static __maybe_unused struct page *try_grab_compound_head(struct page *page,
int refs,
unsigned int flags)
{
bool vendor_ret = false;
trace_android_vh_try_grab_compound_head(page, refs, flags, &vendor_ret);
if (vendor_ret)
return NULL;
if (flags & FOLL_GET) {
struct page *head = try_get_compound_head(page, refs);
if (head)
@@ -1760,6 +1769,8 @@ static long __get_user_pages_remote(struct mm_struct *mm,
unsigned int gup_flags, struct page **pages,
struct vm_area_struct **vmas, int *locked)
{
trace_android_vh___get_user_pages_remote(locked, &gup_flags);
/*
* Parts of FOLL_LONGTERM behavior are incompatible with
* FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on
@@ -1898,6 +1909,8 @@ long get_user_pages(unsigned long start, unsigned long nr_pages,
if (!is_valid_gup_flags(gup_flags))
return -EINVAL;
trace_android_vh_get_user_pages(&gup_flags);
return __gup_longterm_locked(current->mm, start, nr_pages,
pages, vmas, gup_flags | FOLL_TOUCH);
}
@@ -2707,6 +2720,7 @@ static int internal_get_user_pages_fast(unsigned long start,
/* Slow path: try to get the remaining pages with get_user_pages */
start += nr_pinned << PAGE_SHIFT;
pages += nr_pinned;
trace_android_vh_internal_get_user_pages_fast(&gup_flags);
ret = __gup_longterm_unlocked(start, nr_pages - nr_pinned, gup_flags,
pages);
if (ret < 0) {
@@ -2932,6 +2946,7 @@ long pin_user_pages(unsigned long start, unsigned long nr_pages,
return -EINVAL;
gup_flags |= FOLL_PIN;
trace_android_vh_pin_user_pages(&gup_flags);
return __gup_longterm_locked(current->mm, start, nr_pages,
pages, vmas, gup_flags);
}