CRIU must frequently determine if system resources (such as file descriptions, memory mappings, or namespaces) are shared between different processes. While some objects have unique kernel-provided IDs (like inode numbers for files on disk), many do not. This document explains how CRIU uses the kcmp() system call and red-black trees to efficiently detect these shared objects.
Comparing every resource in every process against every other process would result in $O(N^2)$ complexity, where $N$ is the total number of resources (e.g., 100 tasks with 100 files each = 10,000 files, or 50 million pairs). This is prohibitively slow.
kcmp() and Pointer ComparisonThe kcmp() system call identifies whether two kernel objects are the same. Crucially, its return value is not a simple boolean; it returns the result of an internal kernel pointer comparison:
This ordering information allows CRIU to use red-black trees to sort and search for objects with $O(N \log N)$ complexity.
To further optimize performance and minimize the number of expensive kcmp() system calls, CRIU uses a two-level tree structure:
CRIU first calculates a “generation ID” (genid) using cheap, locally available metadata. For regular files, this is derived from the device ID, inode number, and current file position.
genid.genids, they are guaranteed to be different, and no system call is needed.If two objects have identical genids, they might be the same.
genid.kcmp() system call.kcmp() returns 0, the objects are confirmed as shared.CRIU uses kcmp() for various object types, including: