diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index c1c7dc70e0f8..6d4f9f780f3b 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -331,3 +331,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_use_vm_swappiness); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_scan_control); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_signal); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_process_madvise_bypass); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_pageout_return_error); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_process_madvise_return_error); diff --git a/include/trace/hooks/madvise.h b/include/trace/hooks/madvise.h index f899a085fa5c..a92912c02a21 100644 --- a/include/trace/hooks/madvise.h +++ b/include/trace/hooks/madvise.h @@ -11,6 +11,12 @@ DECLARE_RESTRICTED_HOOK(android_rvh_process_madvise_bypass, TP_PROTO(int pidfd, const struct iovec __user *vec, size_t vlen, int behavior, unsigned int flags, ssize_t *ret, bool *bypass), TP_ARGS(pidfd, vec, vlen, behavior, flags, ret, bypass), 1); +DECLARE_HOOK(android_vh_madvise_pageout_return_error, + TP_PROTO(int ret, bool *return_error), + TP_ARGS(ret, return_error)); +DECLARE_HOOK(android_vh_process_madvise_return_error, + TP_PROTO(int behavior, int ret, bool *return_error), + TP_ARGS(behavior, ret, return_error)); #endif diff --git a/mm/madvise.c b/mm/madvise.c index c081e3e92749..10fd7f23a04a 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -599,7 +599,7 @@ static long madvise_cold(struct vm_area_struct *vma, return 0; } -static void madvise_pageout_page_range(struct mmu_gather *tlb, +static int madvise_pageout_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long addr, unsigned long end) { @@ -607,10 +607,13 @@ static void madvise_pageout_page_range(struct mmu_gather *tlb, .pageout = true, .tlb = tlb, }; + int ret; tlb_start_vma(tlb, vma); - walk_page_range(vma->vm_mm, addr, end, &cold_walk_ops, &walk_private); + ret = walk_page_range(vma->vm_mm, addr, end, &cold_walk_ops, &walk_private); tlb_end_vma(tlb, vma); + + return ret; } static long madvise_pageout(struct vm_area_struct *vma, @@ -619,6 +622,8 @@ static long madvise_pageout(struct vm_area_struct *vma, { struct mm_struct *mm = vma->vm_mm; struct mmu_gather tlb; + int ret; + bool return_error = false; *prev = vma; if (!can_madv_lru_vma(vma)) @@ -636,9 +641,13 @@ static long madvise_pageout(struct vm_area_struct *vma, lru_add_drain(); tlb_gather_mmu(&tlb, mm); - madvise_pageout_page_range(&tlb, vma, start_addr, end_addr); + ret = madvise_pageout_page_range(&tlb, vma, start_addr, end_addr); tlb_finish_mmu(&tlb); + trace_android_vh_madvise_pageout_return_error(ret, &return_error); + if (return_error) + return (long)ret; + return 0; } @@ -1492,6 +1501,7 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec, size_t total_len; unsigned int f_flags; bool bypass = false; + bool return_error = false; trace_android_rvh_process_madvise_bypass(pidfd, vec, vlen, behavior, flags, &ret, &bypass); @@ -1547,6 +1557,9 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec, break; iov_iter_advance(&iter, iter_iov_len(&iter)); } + trace_android_vh_process_madvise_return_error(behavior, ret, &return_error); + if (return_error) + goto release_mm; ret = (total_len - iov_iter_count(&iter)) ? : ret;