A process can consume memory on behalf of work that is coordinated elsewhere. Linux process_madvise() lets that external coordinator apply selected virtual-memory advice to ranges in the target process without injecting code into it. The target is identified by a pidfd, while the ranges are supplied as an array of struct iovec.

That arrangement separates memory-policy decisions from the code that owns the mapping. A runtime manager, service supervisor, or memory controller can request reclaim-oriented or prefetch-oriented treatment for another process, subject to kernel support and permission checks. The system call does not transfer ownership of the mapping, freeze the target, or make its address space stable.

A pidfd identifies the process, while iovec identifies virtual ranges

process_madvise() accepts a pidfd, an iovec array, an element count, an advice value, and a flags argument. Each iov_base and iov_len pair describes a virtual address range in the process referenced by the pidfd.

Using a pidfd matters because the operation is attached to a process reference rather than relying only on a numeric PID supplied at the moment of the call. This fits the broader pidfd model for process-oriented APIs and avoids designing the control operation around repeated numeric-PID lookup.

The address values still belong to the target address space. A pointer meaningful in the controller has no special relation to the same numeric address in the target. Software that selects ranges therefore needs a separate, valid source for the target’s mapping layout or an application protocol that already defines those ranges.

The flags argument is reserved and currently must be zero. Treating it as an extension field rather than application-defined bits preserves compatibility with future kernel semantics.

Advice changes kernel treatment, not address-space ownership

For another process, the accepted advice set is deliberately narrower than the full madvise() surface. Current Linux documentation lists MADV_COLD, MADV_COLLAPSE, MADV_PAGEOUT, and MADV_WILLNEED for cross-process operation. Since Linux 6.13, a caller targeting itself can use any advice value accepted for that case.

These operations have different effects. MADV_COLD marks eligible pages as colder candidates for reclaim. MADV_PAGEOUT requests page reclamation for the specified range. MADV_WILLNEED indicates expected near-future access and can trigger read-ahead behavior where applicable. MADV_COLLAPSE requests synchronous collapse into transparent huge pages for eligible memory.

The API therefore carries policy requests with advice-specific semantics. It is not a remote munmap(), a remote allocator, or a generic memory editor. The target process retains its mappings and continues executing while the kernel applies the requested treatment.

The target can mutate its mappings concurrently

A pidfd stabilizes process identity, not the layout of the target’s virtual memory. Another thread can unmap, remap, split, replace, or change a region while a controller is preparing or issuing advice.

This creates a boundary that control-plane code must keep explicit. A range observed earlier is not a permanent handle to a mapping. If the application requires advice to correspond to a particular allocation or generation, that relationship needs synchronization or versioning outside process_madvise().

The kernel reports failures such as inaccessible target ranges, but an error is not a transaction rollback mechanism for a larger application protocol. The caller must still decide whether stale range information can be retried, discarded, or reconciled with newer mapping metadata.

Success can cover fewer bytes than requested

The return value is the number of bytes successfully advised. It can be smaller than the total length represented by the iovec array if processing reaches an error after earlier elements have already been handled.

That partial-result behavior is significant for controllers that submit several disjoint ranges in one call. A nonnegative return does not imply that every requested byte received the advice. The returned byte count must be compared with the requested total when completeness is part of the policy.

This also means batching is not atomic. Combining ranges reduces system-call traffic, but it does not turn the array into a single all-or-nothing memory-management transaction. Recovery logic needs to preserve the distinction between already processed bytes and ranges that still require action.

Permission is part of the interface boundary

Cross-process memory advice can materially affect another process’s performance and resident memory behavior, so Linux applies access checks rather than allowing arbitrary processes to issue it.

The permission model has changed since the system call first appeared in Linux 5.10. The initial implementation used a ptrace-style attach access check. Linux 5.12 relaxed the model so full control of the target was no longer required, while still retaining permission constraints for cross-process operation.

Code should therefore treat EPERM as an operational boundary, not as evidence that the pidfd is invalid. EBADF covers a descriptor that is not a valid pidfd, while ESRCH can report a target that no longer exists. Capability and security-policy configuration remain deployment concerns around the API.

Kernel support is also configuration-dependent through CONFIG_ADVISE_SYSCALLS. A portable Linux deployment cannot infer availability solely from kernel version.

Reclaim advice can trade current RSS for later fault cost

Remote advice is useful precisely because memory pressure and application activity are not always visible from the same component. A supervisor may have a broader view of service priority or host pressure than an individual worker.

With MADV_PAGEOUT or MADV_COLD, that broader view can influence reclaim decisions for selected ranges. The immediate objective may be to reduce pressure from memory that is currently low priority. If the target touches those pages again, however, later accesses can incur work to make the data resident again.

That trade is workload-specific. Aggressive external reclaim can convert memory pressure into latency spikes or I/O. The syscall provides a mechanism for expressing the decision; it does not establish that the decision is beneficial for a particular service.

MADV_WILLNEED points in the opposite direction by signaling expected access. It can be useful when an orchestrating component has reliable phase information, but speculative prefetch can also consume bandwidth and cache capacity. External policy remains accountable for those costs.

Cross-process advice creates a control-plane primitive

process_madvise() is most useful when memory ownership and memory policy are intentionally separated. The target process owns and accesses the mappings; another component can apply a constrained set of kernel memory hints or directions to selected ranges.

The API’s boundaries keep that separation precise: pidfd supplies process identity, iovec supplies virtual ranges, advice values define the requested memory action, permissions restrict who may act, and the byte-count return exposes partial completion.

Those properties make the syscall suitable for coordinated memory management without turning it into a remote memory transaction. Correct integration still depends on fresh mapping information, advice-specific semantics, explicit handling of partial results, and a policy that accounts for the target’s future access pattern.