android_kernel_xiaomi_sm7250/kernel
Minchan Kim 1c21fc048c BACKPORT: mm/madvise: introduce process_madvise() syscall: an external memory hinting API
There is usecase that System Management Software(SMS) want to give a
memory hint like MADV_[COLD|PAGEEOUT] to other processes and in the
case of Android, it is the ActivityManagerService.

The information required to make the reclaim decision is not known to the
app.  Instead, it is known to the centralized userspace
daemon(ActivityManagerService), and that daemon must be able to initiate
reclaim on its own without any app involvement.

To solve the issue, this patch introduces a new syscall
process_madvise(2).  It uses pidfd of an external process to give the
hint.  It also supports vector address range because Android app has
thousands of vmas due to zygote so it's totally waste of CPU and power if
we should call the syscall one by one for each vma.(With testing 2000-vma
syscall vs 1-vector syscall, it showed 15% performance improvement.  I
think it would be bigger in real practice because the testing ran very
cache friendly environment).

Another potential use case for the vector range is to amortize the cost
ofTLB shootdowns for multiple ranges when using MADV_DONTNEED; this could
benefit users like TCP receive zerocopy and malloc implementations.  In
future, we could find more usecases for other advises so let's make it
happens as API since we introduce a new syscall at this moment.  With
that, existing madvise(2) user could replace it with process_madvise(2)
with their own pid if they want to have batch address ranges support
feature.

ince it could affect other process's address range, only privileged
process(PTRACE_MODE_ATTACH_FSCREDS) or something else(e.g., being the same
UID) gives it the right to ptrace the process could use it successfully.
The flag argument is reserved for future use if we need to extend the API.

I think supporting all hints madvise has/will supported/support to
process_madvise is rather risky.  Because we are not sure all hints make
sense from external process and implementation for the hint may rely on
the caller being in the current context so it could be error-prone.  Thus,
I just limited hints as MADV_[COLD|PAGEOUT] in this patch.

If someone want to add other hints, we could hear the usecase and review
it for each hint.  It's safer for maintenance rather than introducing a
buggy syscall but hard to fix it later.

So finally, the API is as follows,

      ssize_t process_madvise(int pidfd, const struct iovec *iovec,
                unsigned long vlen, int advice, unsigned int flags);

    DESCRIPTION
      The process_madvise() system call is used to give advice or directions
      to the kernel about the address ranges from external process as well as
      local process. It provides the advice to address ranges of process
      described by iovec and vlen. The goal of such advice is to improve
      system or application performance.

      The pidfd selects the process referred to by the PID file descriptor
      specified in pidfd. (See pidofd_open(2) for further information)

      The pointer iovec points to an array of iovec structures, defined in
      <sys/uio.h> as:

        struct iovec {
            void *iov_base;         /* starting address */
            size_t iov_len;         /* number of bytes to be advised */
        };

      The iovec describes address ranges beginning at address(iov_base)
      and with size length of bytes(iov_len).

      The vlen represents the number of elements in iovec.

      The advice is indicated in the advice argument, which is one of the
      following at this moment if the target process specified by pidfd is
      external.

        MADV_COLD
        MADV_PAGEOUT

      Permission to provide a hint to external process is governed by a
      ptrace access mode PTRACE_MODE_ATTACH_FSCREDS check; see ptrace(2).

      The process_madvise supports every advice madvise(2) has if target
      process is in same thread group with calling process so user could
      use process_madvise(2) to extend existing madvise(2) to support
      vector address ranges.

    RETURN VALUE
      On success, process_madvise() returns the number of bytes advised.
      This return value may be less than the total number of requested
      bytes, if an error occurred. The caller should check return value
      to determine whether a partial advice occurred.

FAQ:

Q.1 - Why does any external entity have better knowledge?

Quote from Sandeep

"For Android, every application (including the special SystemServer)
are forked from Zygote.  The reason of course is to share as many
libraries and classes between the two as possible to benefit from the
preloading during boot.

After applications start, (almost) all of the APIs end up calling into
this SystemServer process over IPC (binder) and back to the
application.

In a fully running system, the SystemServer monitors every single
process periodically to calculate their PSS / RSS and also decides
which process is "important" to the user for interactivity.

So, because of how these processes start _and_ the fact that the
SystemServer is looping to monitor each process, it does tend to *know*
which address range of the application is not used / useful.

Besides, we can never rely on applications to clean things up
themselves.  We've had the "hey app1, the system is low on memory,
please trim your memory usage down" notifications for a long time[1].
They rely on applications honoring the broadcasts and very few do.

So, if we want to avoid the inevitable killing of the application and
restarting it, some way to be able to tell the OS about unimportant
memory in these applications will be useful.

- ssp

Q.2 - How to guarantee the race(i.e., object validation) between when
giving a hint from an external process and get the hint from the target
process?

process_madvise operates on the target process's address space as it
exists at the instant that process_madvise is called.  If the space
target process can run between the time the process_madvise process
inspects the target process address space and the time that
process_madvise is actually called, process_madvise may operate on
memory regions that the calling process does not expect.  It's the
responsibility of the process calling process_madvise to close this
race condition.  For example, the calling process can suspend the
target process with ptrace, SIGSTOP, or the freezer cgroup so that it
doesn't have an opportunity to change its own address space before
process_madvise is called.  Another option is to operate on memory
regions that the caller knows a priori will be unchanged in the target
process.  Yet another option is to accept the race for certain
process_madvise calls after reasoning that mistargeting will do no
harm.  The suggested API itself does not provide synchronization.  It
also apply other APIs like move_pages, process_vm_write.

The race isn't really a problem though.  Why is it so wrong to require
that callers do their own synchronization in some manner?  Nobody
objects to write(2) merely because it's possible for two processes to
open the same file and clobber each other's writes --- instead, we tell
people to use flock or something.  Think about mmap.  It never
guarantees newly allocated address space is still valid when the user
tries to access it because other threads could unmap the memory right
before.  That's where we need synchronization by using other API or
design from userside.  It shouldn't be part of API itself.  If someone
needs more fine-grained synchronization rather than process level,
there were two ideas suggested - cookie[2] and anon-fd[3].  Both are
applicable via using last reserved argument of the API but I don't
think it's necessary right now since we have already ways to prevent
the race so don't want to add additional complexity with more
fine-grained optimization model.

To make the API extend, it reserved an unsigned long as last argument
so we could support it in future if someone really needs it.

Q.3 - Why doesn't ptrace work?

Injecting an madvise in the target process using ptrace would not work
for us because such injected madvise would have to be executed by the
target process, which means that process would have to be runnable and
that creates the risk of the abovementioned race and hinting a wrong
VMA.  Furthermore, we want to act the hint in caller's context, not the
callee's, because the callee is usually limited in cpuset/cgroups or
even freezed state so they can't act by themselves quick enough, which
causes more thrashing/kill.  It doesn't work if the target process are
ptraced(e.g., strace, debugger, minidump) because a process can have at
most one ptracer.

[1] https://developer.android.com/topic/performance/memory"

[2] process_getinfo for getting the cookie which is updated whenever
    vma of process address layout are changed - Daniel Colascione -
    https://lore.kernel.org/lkml/20190520035254.57579-1-minchan@kernel.org/T/#m7694416fd179b2066a2c62b5b139b14e3894e224

[3] anonymous fd which is used for the object(i.e., address range)
    validation - Michal Hocko -
    https://lore.kernel.org/lkml/20200120112722.GY18451@dhcp22.suse.cz/

[minchan@kernel.org: fix process_madvise build break for arm64]
  Link: http://lkml.kernel.org/r/20200303145756.GA219683@google.com
[minchan@kernel.org: fix build error for mips of process_madvise]
  Link: http://lkml.kernel.org/r/20200508052517.GA197378@google.com
[akpm@linux-foundation.org: fix patch ordering issue]
[akpm@linux-foundation.org: fix arm64 whoops]
[minchan@kernel.org: make process_madvise() vlen arg have type size_t, per Florian]
[akpm@linux-foundation.org: fix i386 build]
[sfr@canb.auug.org.au: fix syscall numbering]
  Link: https://lkml.kernel.org/r/20200905142639.49fc3f1a@canb.auug.org.au
[sfr@canb.auug.org.au: madvise.c needs compat.h]
  Link: https://lkml.kernel.org/r/20200908204547.285646b4@canb.auug.org.au
[minchan@kernel.org: fix mips build]
  Link: https://lkml.kernel.org/r/20200909173655.GC2435453@google.com
[yuehaibing@huawei.com: remove duplicate header which is included twice]
  Link: https://lkml.kernel.org/r/20200915121550.30584-1-yuehaibing@huawei.com
[minchan@kernel.org: do not use helper functions for process_madvise]
  Link: https://lkml.kernel.org/r/20200921175539.GB387368@google.com
[akpm@linux-foundation.org: pidfd_get_pid() gained an argument]
[sfr@canb.auug.org.au: fix up for "iov_iter: transparently handle compat iovecs in import_iovec"]
  Link: https://lkml.kernel.org/r/20200928212542.468e1fef@canb.auug.org.au

Signed-off-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: David Rientjes <rientjes@google.com>
Cc: Alexander Duyck <alexander.h.duyck@linux.intel.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Christian Brauner <christian@brauner.io>
Cc: Daniel Colascione <dancol@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Joel Fernandes <joel@joelfernandes.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: John Dias <joaodias@google.com>
Cc: Kirill Tkhai <ktkhai@virtuozzo.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oleksandr Natalenko <oleksandr@redhat.com>
Cc: Sandeep Patil <sspatil@google.com>
Cc: SeongJae Park <sj38.park@gmail.com>
Cc: SeongJae Park <sjpark@amazon.de>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Sonny Rao <sonnyrao@google.com>
Cc: Tim Murray <timmurray@google.com>
Cc: Christian Brauner <christian.brauner@ubuntu.com>
Cc: Florian Weimer <fw@deneb.enyo.de>
Cc: <linux-man@vger.kernel.org>
Link: http://lkml.kernel.org/r/20200302193630.68771-3-minchan@kernel.org
Link: http://lkml.kernel.org/r/20200508183320.GA125527@google.com
Link: http://lkml.kernel.org/r/20200622192900.22757-4-minchan@kernel.org
Link: https://lkml.kernel.org/r/20200901000633.1920247-4-minchan@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: UtsavBalar1231 <utsavbalar1231@gmail.com>
Change-Id: I8aaf9794564361e2f9c42fb139b38bfe7b63dc65
2022-11-12 11:23:10 +00:00
..
bpf This is the 4.19.262 stable release 2022-10-30 16:23:17 +01:00
cgroup FROMLIST: mm: multi-gen LRU: kill switch 2022-11-12 11:21:16 +00:00
configs
debug Merge tag 'ASB-2021-04-05_4.19-stable' of https://github.com/aosp-mirror/kernel_common into android12-base 2022-02-26 15:09:41 +05:30
dma Merge remote-tracking branch 'aosp/android-4.19-stable' into android12-base 2022-07-09 10:34:17 +05:30
events mm/mmap.c: use IS_ERR_VALUE to check return value of get_unmapped_area 2022-11-12 11:21:20 +00:00
gcov This is the 4.19.262 stable release 2022-10-30 16:23:17 +01:00
irq irq: silence 'irq no longer affine' messages 2022-11-12 11:19:54 +00:00
livepatch livepatch: fix race between fork and KLP transition 2022-10-26 13:19:23 +02:00
locking Merge tag 'ASB-2021-12-05_4.19-stable' of https://github.com/aosp-mirror/kernel_common into android12-base 2022-02-26 20:17:00 +05:30
power PM / sleep: Skip OOM killer toggles when kernel is compiled for Android 2022-11-12 11:21:40 +00:00
printk printk: silence healthd and batteryd logs 2022-11-12 11:19:57 +00:00
rcu rcu: fix a performance regression 2022-11-12 11:19:51 +00:00
sched BACKPORT: ia64/tlb: Eradicate tlb_migrate_finish() callback 2022-11-12 11:23:07 +00:00
time BACKPORT: timers: implement usleep_idle_range() 2022-11-12 11:22:50 +00:00
trace Merge branch 'android-4.19-stable' of https://github.com/aosp-mirror/kernel_common into skizo-x 2022-11-12 11:18:12 +00:00
.gitignore BACKPORT: Provide in-kernel headers to make extending kernel easier 2019-06-12 12:33:20 +00:00
acct.c acct_on(): don't mess with freeze protection 2019-05-31 06:46:05 -07:00
async.c Revert "module, async: async_synchronize_full() on module init iff async is used" 2022-02-23 11:58:38 +01:00
audit_fsnotify.c audit: fix potential double free on error path from fsnotify_add_inode_mark 2022-09-05 10:26:28 +02:00
audit_tree.c audit: Embed key into chunk 2019-12-13 08:51:11 +01:00
audit_watch.c audit: CONFIG_CHANGE don't log internal bookkeeping as an event 2020-10-01 13:14:33 +02:00
audit.c audit: improve audit queue handling when "audit=1" on cmdline 2022-02-08 18:23:13 +01:00
audit.h audit: fix a net reference leak in audit_list_rules_send() 2020-06-22 09:05:13 +02:00
auditfilter.c audit: fix a net reference leak in audit_list_rules_send() 2020-06-22 09:05:13 +02:00
auditsc.c audit: print empty EXECVE args 2019-12-01 09:17:17 +01:00
backtracetest.c
bounds.c FROMLIST: mm: multi-gen LRU: minimal implementation 2022-11-12 11:21:16 +00:00
capability.c LSM: generalize flag passing to security_capable 2020-01-23 08:21:29 +01:00
cfi.c ANDROID: cfi: fix export symbol types 2020-04-29 19:16:15 +02:00
compat.c make 'user_access_begin()' do 'access_ok()' 2020-06-22 09:04:58 +02:00
configs.c
context_tracking.c
cpu_pm.c Merge android-4.19-stable.136 (204dd19) into msm-4.19 2020-10-14 20:04:29 +05:30
cpu.c Merge branch 'android-4.19-stable' of https://github.com/aosp-mirror/kernel_common into skizo-x 2022-11-12 11:18:12 +00:00
crash_core.c
crash_dump.c
cred.c memcg: account security cred as well to kmemcg 2020-01-09 10:19:00 +01:00
delayacct.c UPSTREAM: delayacct: track delays from thrashing cache pages 2019-03-21 16:25:26 -07:00
dma.c
exec_domain.c
exit.c UPSTREAM: pid: move pidfd_get_pid() to pid.c 2022-11-12 11:23:08 +00:00
extable.c
fail_function.c fail_function: Remove a redundant mutex unlock 2020-11-24 13:27:23 +01:00
fork.c BACKPORT: pidfd: add P_PIDFD to waitid() 2022-11-12 11:23:08 +00:00
freezer.c
futex.c Merge tag 'ASB-2021-01-05_4.19-stable' of https://github.com/aosp-mirror/kernel_common into android12-base 2022-02-26 14:49:12 +05:30
gen_kheaders.sh kheaders: include only headers into kheaders_data.tar.xz 2020-06-11 05:00:06 -07:00
groups.c
hung_task.c hung task: check specific tasks for long uninterruptible sleep state 2019-08-02 12:42:25 -07:00
iomem.c
irq_work.c irq_work: Do not raise an IPI when queueing work on the local CPU 2019-05-31 06:46:19 -07:00
jump_label.c locking/static_key: Fix false positive warnings on concurrent dec/inc 2021-03-04 09:39:30 +01:00
kallsyms.c Merge 4.19.133 into android-4.19-stable 2020-07-17 07:54:52 +02:00
kcmp.c
Kconfig.freezer
Kconfig.hz
Kconfig.locks locking/rwsem: for rwsem prio aware enhancement 2019-05-24 15:32:11 +08:00
Kconfig.preempt
kcov.c UPSTREAM: kcov: remote coverage support 2020-01-15 14:51:23 +00:00
kexec_core.c kernel: kexec: remove the lock operation of system_transition_mutex 2021-02-03 23:23:23 +01:00
kexec_file.c kexec_file: drop weak attribute from arch_kexec_apply_relocations[_add] 2022-07-02 16:27:39 +02:00
kexec_internal.h
kexec.c
kheaders.c BACKPORT: kheaders: Move from proc to sysfs 2019-06-12 12:33:54 +00:00
kmod.c kmod: make request_module() return an error when autoloading is disabled 2020-04-17 10:48:52 +02:00
kprobes.c kprobes: Prohibit probes in gate area 2022-09-15 12:17:05 +02:00
ksysfs.c
kthread.c This is the 4.19.197 stable release 2021-07-11 21:33:34 +02:00
latencytop.c
Makefile kernel: Use the stock config for /proc/config.gz 2022-11-12 11:19:20 +00:00
memremap.c BACKPORT: mm: remove superfluous __ClearPageActive() 2022-11-12 11:21:13 +00:00
module_signing.c
module-internal.h
module.c Merge tag 'ASB-2022-03-05_4.19-stable' of https://github.com/aosp-mirror/kernel_common into android12-base 2022-03-08 06:44:12 +05:30
notifier.c Merge "Merge android-4.19-stable.113 (2b82910d) into msm-4.19" 2020-07-24 22:21:24 -07:00
nsproxy.c
padata.c Revert "padata: validate cpumask without removed CPU during offline" 2021-08-09 16:20:31 +02:00
panic.c Merge android-4.19-stable.125 (a483478) into msm-4.19 2020-09-20 23:45:10 +05:30
params.c ANDROID: GKI: export symbols from abi_gki_aarch64_qcom_whitelist 2020-04-13 21:36:41 +00:00
pid_namespace.c memcg: enable accounting for pids in nested pid namespaces 2021-09-22 11:48:09 +02:00
pid.c UPSTREAM: pid: move pidfd_get_pid() to pid.c 2022-11-12 11:23:08 +00:00
profile.c profiling: fix shift too large makes kernel panic 2022-08-25 11:15:20 +02:00
ptrace.c ptrace: Reimplement PTRACE_KILL by always sending SIGKILL 2022-06-14 16:59:14 +02:00
range.c
reboot.c Merge 4.19.158 into android-4.19-stable 2020-11-19 12:25:33 +01:00
relay.c kernel/relay.c: fix memleak on destroy relay channel 2020-08-26 10:30:59 +02:00
resource.c resource: fix locking in find_next_iomem_res() 2019-09-16 08:22:20 +02:00
rseq.c
scs.c FROMLIST: scs: add support for stack usage debugging 2019-11-27 12:37:25 -08:00
seccomp.c seccomp: Invalidate seccomp mode to catch death failures 2022-02-16 12:51:47 +01:00
signal.c BACKPORT: pidfd: add P_PIDFD to waitid() 2022-11-12 11:23:08 +00:00
smp.c smp: Fix smp_call_function_single_async prototype 2022-05-11 07:51:40 +05:30
smpboot.c kthread: Extract KTHREAD_IS_PER_CPU 2021-02-07 14:48:38 +01:00
smpboot.h
softirq.c trace: Add trace points for tasklet entry/exit 2020-01-28 20:45:01 -08:00
stacktrace.c
stop_machine.c UPSTREAM: stop_machine: Fix stop_cpus_in_progress ordering 2022-11-12 11:20:54 +00:00
sys_ni.c BACKPORT: mm/madvise: introduce process_madvise() syscall: an external memory hinting API 2022-11-12 11:23:10 +00:00
sys.c This is the 4.19.208 stable release 2021-10-04 19:05:27 +02:00
sysctl_binary.c
sysctl.c mm: compaction: allow using different proactiveness value depending on the screen state 2022-11-12 11:22:27 +00:00
task_work.c
taskstats.c taskstats: extended taskstats2 with acct fields 2020-05-13 22:59:08 -07:00
test_kprobes.c
torture.c
tracepoint.c tracepoint: Add tracepoint_probe_register_may_exist() for BPF tracing 2021-07-20 16:15:42 +02:00
tsacct.c taskstats: Cleanup the use of task->exit_code 2022-02-23 11:58:39 +01:00
ucount.c
uid16.c
uid16.h
umh.c usermodehelper: reset umask to default before executing user process 2020-10-14 10:31:21 +02:00
up.c smp: Fix smp_call_function_single_async prototype 2022-05-11 07:51:40 +05:30
user_namespace.c
user-return-notifier.c
user.c ANDROID: proc: Add /proc/uid directory 2019-03-06 15:59:21 +00:00
utsname_sysctl.c
utsname.c
watchdog_hld.c
watchdog.c Merge remote-tracking branch 'aosp/android-4.19-stable' into android12-base 2022-09-22 14:02:10 +05:30
workqueue_internal.h UPSTREAM: psi: fix aggregation idle shut-off 2019-03-21 16:25:27 -07:00
workqueue.c Merge remote-tracking branch 'aosp/android-4.19-stable' into android12-base 2022-09-29 08:08:04 +05:30