Linux process_madvise(): Advising the Kernel About Another Process's Memory
Use process_madvise() with pidfds and remote address ranges while accounting for permissions, partial results, advice-specific semantics, and kernel versions.
process_madvise() applies memory advice to address ranges in a target process. It is a coordination interface for a manager that already knows which ranges it wants to advise; it does not read the target’s memory, discover useful ranges, or promise that pages will be reclaimed. A pid file descriptor identifies the target, and an array of iovec structures describes virtual-address ranges in that target.
Treat advice as a request, not a command
The API follows the madvise() model. Depending on the kernel and advice, flags such as MADV_COLD, MADV_PAGEOUT, and MADV_WILLNEED communicate intended use to the kernel. The kernel can ignore advice that is not actionable, and reclaim is subject to mapping type, page state, memory pressure, and other kernel decisions. This call is not a replacement for a memory limit or a guarantee that a process’s resident set will shrink by a chosen amount.
ssize_t advised = process_madvise(pidfd, ranges, range_count,
MADV_COLD, 0);
if (advised == -1) {
perror("process_madvise");
} else if ((size_t)advised < requested_bytes) {
/* Record partial progress; do not report the whole request as applied. */
}
The snippet assumes a valid pidfd, a bounded iovec array, a supported advice value, and the GNU declaration in the target C library. The flags argument currently must be zero. Check the target system’s headers and man page rather than assuming all distributions expose the same API surface.
Permissions and compatibility are part of the design
The system call appeared in Linux 5.10 and glibc 2.36. For another process, Linux 5.12 and later apply a ptrace read-style permission check and require CAP_SYS_NICE; the earlier 5.10 permission check was stricter. Remote-process advice is restricted to specific advice values, and Linux 6.13 broadened the advice accepted when the target is the calling process. Probe the actual kernel and privilege context.
The return value is a byte count, not a Boolean. If a later remote range is invalid, advice may already have been applied to earlier ranges; a short positive result must be handled as partial progress. Build the iovec list from validated mappings, cap its length at IOV_MAX, and record target identity and address ranges for diagnostics. Because address maps can change concurrently, coordinate with the target when possible and make stale ranges a recoverable outcome.
Use pidfds to avoid relying on a reusable numeric PID for process identity, but keep the descriptor lifecycle explicit. process_madvise() is most appropriate for cooperating memory-management tools, not as an untrusted cross-process control channel.
Related:
- Linux pidfds: Race-Free Process Handles Beyond Numeric PIDs
- Control Groups (cgroup v2) Explained: Limiting and Accounting for Resources
Sources: